func getSuitableAlgFromCurve(curve elliptic.Curve) (jwt.Algorithm, error) {
	curveBitSize := curve.Params().BitSize
	keyLen := curveBitSize / 8
	if curveBitSize%8 > 0 {
		keyLen++
	}
	var alg jwt.Algorithm
	switch 2 * keyLen {
	case 64:
		alg = jwt.ES256
	case 96:
		alg = jwt.ES384
	case 132:
		alg = jwt.ES512
	default:
		return jwt.NONE, fmt.Errorf("invalid key length %d", keyLen)
	}
	return alg, nil
}
getSuitableAlgFromCurve inspects the key length in curve, and determines the
corresponding jwt.Algorithm.
package main
import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rsa"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"github.com/mattn/go-isatty"
	"github.com/kenshaw/jwt"
	"github.com/kenshaw/pemutil"
)
func main() {
	flagEnc := flag.Bool("enc", false, "encode token from json data provided from stdin, or via name=value pairs passed on the command line")
	flagDec := flag.Bool("dec", false, "decode and verify token read from stdin using the provided key data")
	flagKey := flag.String("k", "", "path to PEM-encoded file or JSON file containing key data")
	flagAlg := flag.String("alg", "", "override signing algorithm")
	flag.Parse()
	if err := run(*flagEnc, *flagDec, *flagKey, *flagAlg, flag.Args()); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}
func run(enc, dec bool, key, algType string, args []string) error {
	switch {
	case key == "":
		return errors.New("must supply a key file with -k")
	case len(args) > 0 && dec:
		return errors.New("unknown args passed for -dec")
	}
	var err error
	var in []byte
	if len(args) > 0 && enc {
		in, err = buildEncArgs(args)
	} else {
		in, err = ioutil.ReadAll(os.Stdin)
	}
	if err != nil {
		return err
	}
	pem, suggestedAlg, err := loadKeyData(key)
	if err != nil {
		return err
	}
	var alg jwt.Algorithm
	switch {
	case suggestedAlg != jwt.NONE:
		alg = suggestedAlg
	case algType != "":
		err = (&alg).UnmarshalText([]byte(algType))
	case dec:
		alg, err = jwt.PeekAlgorithm(in)
	default:
		alg, err = getAlgFromKeyData(pem)
	}
	if err != nil {
		return err
	}
	signer, err := alg.New(pem)
	if err != nil {
		return err
	}
	var out []byte
	switch {
	case dec:
		out, err = doDec(signer, in)
	case enc:
		out, err = doEnc(signer, in)
	default:
		return errors.New("please specify -enc or -dec")
	}
	if err != nil {
		return err
	}
	if isatty.IsTerminal(os.Stdout.Fd()) {
		out = append(out, '\n')
	}
	_, err = os.Stdout.Write(out)
	return err
}
func loadKeyData(path string) (pemutil.Store, jwt.Algorithm, error) {
	buf, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, jwt.NONE, err
	}
	v := make(map[string]interface{})
	if err = json.Unmarshal(buf, &v); err != nil {
		keyset, err := pemutil.LoadFile(path)
		if err != nil {
			return nil, jwt.NONE, err
		}
		return keyset, jwt.NONE, nil
	}
	keyset := pemutil.Store{}
	for _, val := range v {
		if str, ok := val.(string); ok {
			_ = keyset.Decode([]byte(str))
		}
	}
	keyset.AddPublicKeys()
	if len(keyset) < 1 {
		return nil, jwt.NONE, fmt.Errorf("could not find any PEM encoded keys in %s", path)
	}
	if bytes.Contains(buf, []byte("gserviceaccount.com")) {
		return keyset, jwt.RS256, nil
	}
	return keyset, jwt.NONE, nil
}