github.com/mavryk-network/mvgo@v1.19.9/mavryk/key.go (about)

     1  // Copyright (c) 2020-2023 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package mavryk
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"fmt"
    10  	"strings"
    11  
    12  	"crypto/ecdsa"
    13  	"crypto/ed25519"
    14  	"crypto/elliptic"
    15  	"crypto/rand"
    16  
    17  	"github.com/mavryk-network/mvgo/base58"
    18  
    19  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
    20  	"golang.org/x/crypto/blake2b"
    21  )
    22  
    23  var (
    24  	// ErrUnknownKeyType describes an error where a type for a
    25  	// public key is undefined.
    26  	ErrUnknownKeyType = errors.New("tezos: unknown key type")
    27  
    28  	// ErrPassphrase is returned when a required passphrase is missing
    29  	ErrPassphrase = errors.New("tezos: passphrase required")
    30  
    31  	InvalidKey = Key{Type: KeyTypeInvalid, Data: nil}
    32  
    33  	// Digest is an alias for blake2b checksum algorithm
    34  	Digest = blake2b.Sum256
    35  )
    36  
    37  // PassphraseFunc is a callback used to obtain a passphrase for decrypting a private key
    38  type PassphraseFunc func() ([]byte, error)
    39  
    40  // KeyType is a type that describes which cryptograhic curve is used by a public or
    41  // private key
    42  type KeyType byte
    43  
    44  const (
    45  	KeyTypeEd25519 KeyType = iota
    46  	KeyTypeSecp256k1
    47  	KeyTypeP256
    48  	KeyTypeBls12_381
    49  	KeyTypeInvalid
    50  )
    51  
    52  func (t KeyType) IsValid() bool {
    53  	return t < KeyTypeInvalid
    54  }
    55  
    56  func (t KeyType) String() string {
    57  	return t.PkPrefix()
    58  }
    59  
    60  func (t KeyType) Curve() elliptic.Curve {
    61  	switch t {
    62  	case KeyTypeSecp256k1:
    63  		return secp256k1.S256()
    64  	case KeyTypeP256:
    65  		return elliptic.P256()
    66  	default:
    67  		return nil
    68  	}
    69  }
    70  
    71  func (t KeyType) PkHashType() HashType {
    72  	switch t {
    73  	case KeyTypeEd25519:
    74  		return HashTypePkEd25519
    75  	case KeyTypeSecp256k1:
    76  		return HashTypePkSecp256k1
    77  	case KeyTypeP256:
    78  		return HashTypePkP256
    79  	case KeyTypeBls12_381:
    80  		return HashTypePkBls12_381
    81  	default:
    82  		return HashTypeInvalid
    83  	}
    84  }
    85  
    86  func (t KeyType) SkHashType() HashType {
    87  	switch t {
    88  	case KeyTypeEd25519:
    89  		return HashTypeSkEd25519
    90  	case KeyTypeSecp256k1:
    91  		return HashTypeSkSecp256k1
    92  	case KeyTypeP256:
    93  		return HashTypeSkP256
    94  	case KeyTypeBls12_381:
    95  		return HashTypeSkBls12_381
    96  	default:
    97  		return HashTypeInvalid
    98  	}
    99  }
   100  
   101  func (t KeyType) AddressType() AddressType {
   102  	switch t {
   103  	case KeyTypeEd25519:
   104  		return AddressTypeEd25519
   105  	case KeyTypeSecp256k1:
   106  		return AddressTypeSecp256k1
   107  	case KeyTypeP256:
   108  		return AddressTypeP256
   109  	case KeyTypeBls12_381:
   110  		return AddressTypeBls12_381
   111  	default:
   112  		return AddressTypeInvalid
   113  	}
   114  }
   115  
   116  func (t KeyType) PkPrefixBytes() []byte {
   117  	switch t {
   118  	case KeyTypeEd25519:
   119  		return ED25519_PUBLIC_KEY_ID
   120  	case KeyTypeSecp256k1:
   121  		return SECP256K1_PUBLIC_KEY_ID
   122  	case KeyTypeP256:
   123  		return P256_PUBLIC_KEY_ID
   124  	case KeyTypeBls12_381:
   125  		return BLS12_381_PUBLIC_KEY_ID
   126  	default:
   127  		return nil
   128  	}
   129  }
   130  
   131  func (t KeyType) PkPrefix() string {
   132  	switch t {
   133  	case KeyTypeEd25519:
   134  		return ED25519_PUBLIC_KEY_PREFIX
   135  	case KeyTypeSecp256k1:
   136  		return SECP256K1_PUBLIC_KEY_PREFIX
   137  	case KeyTypeP256:
   138  		return P256_PUBLIC_KEY_PREFIX
   139  	case KeyTypeBls12_381:
   140  		return BLS12_381_PUBLIC_KEY_PREFIX
   141  	default:
   142  		return ""
   143  	}
   144  }
   145  
   146  func (t KeyType) SkPrefixBytes() []byte {
   147  	switch t {
   148  	case KeyTypeEd25519:
   149  		return ED25519_SEED_ID
   150  	case KeyTypeSecp256k1:
   151  		return SECP256K1_SECRET_KEY_ID
   152  	case KeyTypeP256:
   153  		return P256_SECRET_KEY_ID
   154  	case KeyTypeBls12_381:
   155  		return BLS12_381_SECRET_KEY_ID
   156  	default:
   157  		return nil
   158  	}
   159  }
   160  
   161  func (t KeyType) SkePrefixBytes() []byte {
   162  	switch t {
   163  	case KeyTypeEd25519:
   164  		return ED25519_ENCRYPTED_SEED_ID
   165  	case KeyTypeSecp256k1:
   166  		return SECP256K1_ENCRYPTED_SECRET_KEY_ID
   167  	case KeyTypeP256:
   168  		return P256_ENCRYPTED_SECRET_KEY_ID
   169  	case KeyTypeBls12_381:
   170  		return BLS12_381_SECRET_KEY_ID
   171  	default:
   172  		return nil
   173  	}
   174  }
   175  
   176  func (t KeyType) SkPrefix() string {
   177  	switch t {
   178  	case KeyTypeEd25519:
   179  		return ED25519_SECRET_KEY_PREFIX
   180  	case KeyTypeSecp256k1:
   181  		return SECP256K1_SECRET_KEY_PREFIX
   182  	case KeyTypeP256:
   183  		return P256_SECRET_KEY_PREFIX
   184  	case KeyTypeBls12_381:
   185  		return BLS12_381_SECRET_KEY_PREFIX
   186  	default:
   187  		return ""
   188  	}
   189  }
   190  
   191  func (t KeyType) SkePrefix() string {
   192  	switch t {
   193  	case KeyTypeEd25519:
   194  		return ED25519_ENCRYPTED_SEED_PREFIX
   195  	case KeyTypeSecp256k1:
   196  		return SECP256K1_ENCRYPTED_SECRET_KEY_PREFIX
   197  	case KeyTypeP256:
   198  		return P256_ENCRYPTED_SECRET_KEY_PREFIX
   199  	case KeyTypeBls12_381:
   200  		return BLS12_381_ENCRYPTED_SECRET_KEY_PREFIX
   201  	default:
   202  		return ""
   203  	}
   204  }
   205  
   206  func (t KeyType) Tag() byte {
   207  	switch t {
   208  	case KeyTypeEd25519:
   209  		return 0
   210  	case KeyTypeSecp256k1:
   211  		return 1
   212  	case KeyTypeP256:
   213  		return 2
   214  	case KeyTypeBls12_381:
   215  		return 3
   216  	default:
   217  		return 255
   218  	}
   219  }
   220  
   221  func ParseKeyTag(b byte) KeyType {
   222  	switch b {
   223  	case 0:
   224  		return KeyTypeEd25519
   225  	case 1:
   226  		return KeyTypeSecp256k1
   227  	case 2:
   228  		return KeyTypeP256
   229  	case 3:
   230  		return KeyTypeBls12_381
   231  	default:
   232  		return KeyTypeInvalid
   233  	}
   234  }
   235  
   236  func ParseKeyType(s string) (KeyType, bool) {
   237  	switch s {
   238  	case ED25519_ENCRYPTED_SEED_PREFIX:
   239  		return KeyTypeEd25519, true
   240  	case SECP256K1_ENCRYPTED_SECRET_KEY_PREFIX:
   241  		return KeyTypeSecp256k1, true
   242  	case P256_ENCRYPTED_SECRET_KEY_PREFIX:
   243  		return KeyTypeP256, true
   244  	case BLS12_381_ENCRYPTED_SECRET_KEY_PREFIX:
   245  		return KeyTypeBls12_381, true
   246  	case ED25519_SEED_PREFIX: // same as	ED25519_SECRET_KEY_PREFIX
   247  		return KeyTypeEd25519, false
   248  	case SECP256K1_SECRET_KEY_PREFIX:
   249  		return KeyTypeSecp256k1, false
   250  	case P256_SECRET_KEY_PREFIX:
   251  		return KeyTypeP256, false
   252  	case BLS12_381_SECRET_KEY_PREFIX:
   253  		return KeyTypeBls12_381, false
   254  	default:
   255  		return KeyTypeInvalid, false
   256  	}
   257  }
   258  
   259  func IsPublicKey(s string) bool {
   260  	for _, prefix := range []string{
   261  		ED25519_PUBLIC_KEY_PREFIX,
   262  		SECP256K1_PUBLIC_KEY_PREFIX,
   263  		P256_PUBLIC_KEY_PREFIX,
   264  		BLS12_381_PUBLIC_KEY_PREFIX,
   265  	} {
   266  		if strings.HasPrefix(s, prefix) {
   267  			return true
   268  		}
   269  	}
   270  	return false
   271  }
   272  
   273  func IsPrivateKey(s string) bool {
   274  	for _, prefix := range []string{
   275  		ED25519_SEED_PREFIX,
   276  		ED25519_SECRET_KEY_PREFIX,
   277  		SECP256K1_SECRET_KEY_PREFIX,
   278  		P256_SECRET_KEY_PREFIX,
   279  		BLS12_381_SECRET_KEY_PREFIX,
   280  		ED25519_ENCRYPTED_SEED_PREFIX,
   281  		SECP256K1_ENCRYPTED_SECRET_KEY_PREFIX,
   282  		P256_ENCRYPTED_SECRET_KEY_PREFIX,
   283  		BLS12_381_ENCRYPTED_SECRET_KEY_PREFIX,
   284  	} {
   285  		if strings.HasPrefix(s, prefix) {
   286  			return true
   287  		}
   288  	}
   289  	return false
   290  }
   291  
   292  func IsEncryptedKey(s string) bool {
   293  	for _, prefix := range []string{
   294  		ED25519_ENCRYPTED_SEED_PREFIX,
   295  		SECP256K1_ENCRYPTED_SECRET_KEY_PREFIX,
   296  		P256_ENCRYPTED_SECRET_KEY_PREFIX,
   297  		BLS12_381_ENCRYPTED_SECRET_KEY_PREFIX,
   298  	} {
   299  		if strings.HasPrefix(s, prefix) {
   300  			return true
   301  		}
   302  	}
   303  	return false
   304  }
   305  
   306  func HasKeyPrefix(s string) bool {
   307  	return IsPublicKey(s) || IsPrivateKey(s)
   308  }
   309  
   310  // Key represents a public key on the Tezos blockchain.
   311  type Key struct {
   312  	Type KeyType
   313  	Data []byte
   314  }
   315  
   316  func NewKey(typ KeyType, data []byte) Key {
   317  	return Key{
   318  		Type: typ,
   319  		Data: data,
   320  	}
   321  }
   322  
   323  // Verify verifies the signature using the public key.
   324  func (k Key) Verify(hash []byte, sig Signature) error {
   325  	switch k.Type {
   326  	case KeyTypeEd25519:
   327  		pk := ed25519.PublicKey(k.Data)
   328  		if ok := ed25519.Verify(pk, hash, sig.Data); !ok {
   329  			return ErrSignature
   330  		}
   331  	case KeyTypeSecp256k1, KeyTypeP256:
   332  		curve := k.Type.Curve()
   333  		pk, err := ecUnmarshalCompressed(curve, k.Data)
   334  		if err != nil {
   335  			return err
   336  		}
   337  		if ok := ecVerifySignature(pk, hash, sig); !ok {
   338  			return ErrSignature
   339  		}
   340  	case KeyTypeBls12_381:
   341  		// TODO
   342  	}
   343  	return nil
   344  }
   345  
   346  func (k Key) IsValid() bool {
   347  	return k.Type.IsValid() && k.Type.PkHashType().Len == len(k.Data)
   348  }
   349  
   350  func (k Key) IsEqual(k2 Key) bool {
   351  	return k.Type == k2.Type && bytes.Equal(k.Data, k2.Data)
   352  }
   353  
   354  func (k Key) Clone() Key {
   355  	buf := make([]byte, len(k.Data))
   356  	copy(buf, k.Data)
   357  	return Key{
   358  		Type: k.Type,
   359  		Data: buf,
   360  	}
   361  }
   362  
   363  func (k Key) Hash() []byte {
   364  	h, _ := blake2b.New(20, nil)
   365  	h.Write(k.Data)
   366  	return h.Sum(nil)
   367  }
   368  
   369  func (k Key) Address() Address {
   370  	return NewAddress(k.Type.AddressType(), k.Hash())
   371  }
   372  
   373  func (k Key) String() string {
   374  	if !k.IsValid() {
   375  		return ""
   376  	}
   377  	return base58.CheckEncode(k.Data, k.Type.PkPrefixBytes())
   378  }
   379  
   380  func (k Key) MarshalText() ([]byte, error) {
   381  	return []byte(k.String()), nil
   382  }
   383  
   384  func (k *Key) UnmarshalText(data []byte) error {
   385  	key, err := ParseKey(string(data))
   386  	if err != nil {
   387  		return err
   388  	}
   389  	*k = key
   390  	return nil
   391  }
   392  
   393  func (k Key) MarshalBinary() ([]byte, error) {
   394  	return k.Bytes(), nil
   395  }
   396  
   397  func (k Key) Bytes() []byte {
   398  	if !k.Type.IsValid() || len(k.Data) == 0 {
   399  		return nil
   400  	}
   401  	return append([]byte{k.Type.Tag()}, k.Data...)
   402  }
   403  
   404  func DecodeKey(buf []byte) (Key, error) {
   405  	k := Key{}
   406  	if len(buf) == 0 {
   407  		return k, nil
   408  	}
   409  	if err := k.UnmarshalBinary(buf); err != nil {
   410  		return k, err
   411  	}
   412  	return k, nil
   413  }
   414  
   415  func (k *Key) UnmarshalBinary(b []byte) error {
   416  	l := len(b)
   417  	// allow empty keys
   418  	if l == 0 {
   419  		k.Type = KeyTypeInvalid
   420  		return nil
   421  	}
   422  	// check data size
   423  	if l < 33 {
   424  		return fmt.Errorf("tezos: invalid binary key length %d", l)
   425  	}
   426  	if typ := ParseKeyTag(b[0]); !typ.IsValid() {
   427  		return fmt.Errorf("tezos: invalid binary key type %x", b[0])
   428  	} else {
   429  		k.Type = typ
   430  	}
   431  	if cap(k.Data) < l-1 {
   432  		k.Data = make([]byte, l-1)
   433  	} else {
   434  		k.Data = k.Data[:l-1]
   435  	}
   436  	copy(k.Data, b[1:])
   437  	return nil
   438  }
   439  
   440  func (k *Key) EncodeBuffer(buf *bytes.Buffer) error {
   441  	_, err := buf.Write(k.Bytes())
   442  	return err
   443  }
   444  
   445  func (k *Key) DecodeBuffer(buf *bytes.Buffer) error {
   446  	if l := buf.Len(); l < 33 {
   447  		return fmt.Errorf("tezos: invalid binary key length %d", l)
   448  	}
   449  	tag := buf.Next(1)[0]
   450  	if typ := ParseKeyTag(tag); !typ.IsValid() {
   451  		return fmt.Errorf("tezos: invalid binary key type %x", tag)
   452  	} else {
   453  		k.Type = typ
   454  	}
   455  	l := k.Type.PkHashType().Len
   456  	k.Data = make([]byte, l)
   457  	copy(k.Data, buf.Next(l))
   458  	if !k.IsValid() {
   459  		return fmt.Errorf("tezos: invalid binary key typ=%s len=%d", k.Type, len(k.Data))
   460  	}
   461  	return nil
   462  }
   463  
   464  func ParseKey(s string) (Key, error) {
   465  	k := Key{}
   466  	if len(s) == 0 {
   467  		return k, nil
   468  	}
   469  	decoded, version, err := base58.CheckDecode(s, 4, nil)
   470  	if err != nil {
   471  		if err == base58.ErrChecksum {
   472  			return k, ErrChecksumMismatch
   473  		}
   474  		return k, fmt.Errorf("tezos: unknown format for key %s: %w", s, err)
   475  	}
   476  	switch {
   477  	case bytes.Equal(version, ED25519_PUBLIC_KEY_ID):
   478  		k.Type = KeyTypeEd25519
   479  	case bytes.Equal(version, SECP256K1_PUBLIC_KEY_ID):
   480  		k.Type = KeyTypeSecp256k1
   481  	case bytes.Equal(version, P256_PUBLIC_KEY_ID):
   482  		k.Type = KeyTypeP256
   483  	case bytes.Equal(version, BLS12_381_PUBLIC_KEY_ID):
   484  		k.Type = KeyTypeBls12_381
   485  	default:
   486  		return k, fmt.Errorf("tezos: unknown version %x for key %s", version, s)
   487  	}
   488  	if l := len(decoded); l != k.Type.PkHashType().Len {
   489  		return k, fmt.Errorf("tezos: invalid length %d for %s key data", l, k.Type.PkPrefix())
   490  	}
   491  	k.Data = decoded
   492  	return k, nil
   493  }
   494  
   495  func MustParseKey(key string) Key {
   496  	k, err := ParseKey(key)
   497  	if err != nil {
   498  		panic(err)
   499  	}
   500  	return k
   501  }
   502  
   503  // Set implements the flags.Value interface for use in command line argument parsing.
   504  func (k *Key) Set(key string) (err error) {
   505  	*k, err = ParseKey(key)
   506  	return
   507  }
   508  
   509  // PrivateKey represents a typed private key used for signing messages.
   510  type PrivateKey struct {
   511  	Type KeyType
   512  	Data []byte
   513  }
   514  
   515  func (k PrivateKey) IsValid() bool {
   516  	return k.Type.IsValid() && k.Type.SkHashType().Len == len(k.Data)
   517  }
   518  
   519  func (k PrivateKey) String() string {
   520  	var buf []byte
   521  	switch k.Type {
   522  	case KeyTypeEd25519:
   523  		buf = ed25519.PrivateKey(k.Data).Seed()
   524  	case KeyTypeSecp256k1, KeyTypeP256, KeyTypeBls12_381:
   525  		buf = k.Data
   526  	default:
   527  		return ""
   528  	}
   529  	return base58.CheckEncode(buf, k.Type.SkPrefixBytes())
   530  }
   531  
   532  func (k PrivateKey) Address() Address {
   533  	return k.Public().Address()
   534  }
   535  
   536  func (k PrivateKey) MarshalText() ([]byte, error) {
   537  	return []byte(k.String()), nil
   538  }
   539  
   540  func (k *PrivateKey) UnmarshalText(data []byte) error {
   541  	key, err := ParsePrivateKey(string(data))
   542  	if err != nil {
   543  		return err
   544  	}
   545  	*k = key
   546  	return nil
   547  }
   548  
   549  // GenerateKey creates a random private key.
   550  func GenerateKey(typ KeyType) (PrivateKey, error) {
   551  	key := PrivateKey{
   552  		Type: typ,
   553  	}
   554  	switch typ {
   555  	case KeyTypeEd25519:
   556  		_, sk, err := ed25519.GenerateKey(nil)
   557  		if err != nil {
   558  			return key, err
   559  		}
   560  		key.Data = []byte(sk)
   561  	case KeyTypeSecp256k1, KeyTypeP256:
   562  		curve := typ.Curve()
   563  		ecKey, err := ecdsa.GenerateKey(curve, rand.Reader)
   564  		if err != nil {
   565  			return key, err
   566  		}
   567  		key.Data = make([]byte, typ.SkHashType().Len)
   568  		ecKey.D.FillBytes(key.Data)
   569  	case KeyTypeBls12_381:
   570  		// TODO
   571  	}
   572  	return key, nil
   573  }
   574  
   575  // Public returns the public key associated with the private key.
   576  func (k PrivateKey) Public() Key {
   577  	pk := Key{
   578  		Type: k.Type,
   579  	}
   580  	switch k.Type {
   581  	case KeyTypeEd25519:
   582  		pk.Data = []byte(ed25519.PrivateKey(k.Data).Public().(ed25519.PublicKey))
   583  	case KeyTypeSecp256k1, KeyTypeP256:
   584  		curve := k.Type.Curve()
   585  		ecKey, err := ecPrivateKeyFromBytes(k.Data, curve)
   586  		if err != nil {
   587  			pk.Type = KeyTypeInvalid
   588  			return pk
   589  		}
   590  		pk.Data = elliptic.MarshalCompressed(curve, ecKey.PublicKey.X, ecKey.PublicKey.Y)
   591  	case KeyTypeBls12_381:
   592  		// TODO
   593  	}
   594  	return pk
   595  }
   596  
   597  // Encrypt encrypts the private key with a passphrase obtained from calling fn.
   598  func (k PrivateKey) Encrypt(fn PassphraseFunc) (string, error) {
   599  	var buf []byte
   600  	switch k.Type {
   601  	case KeyTypeEd25519:
   602  		buf = ed25519.PrivateKey(k.Data).Seed()
   603  	case KeyTypeSecp256k1, KeyTypeP256:
   604  		buf = k.Data
   605  	case KeyTypeBls12_381:
   606  		// TODO
   607  	}
   608  	enc, err := encryptPrivateKey(buf, fn)
   609  	if err != nil {
   610  		return "", err
   611  	}
   612  	return base58.CheckEncode(enc, k.Type.SkePrefixBytes()), nil
   613  }
   614  
   615  // Sign signs the digest (hash) of a message with the private key.
   616  func (k PrivateKey) Sign(hash []byte) (Signature, error) {
   617  	switch k.Type {
   618  	case KeyTypeEd25519:
   619  		return Signature{
   620  			Type: SignatureTypeEd25519,
   621  			Data: ed25519.Sign(ed25519.PrivateKey(k.Data), hash),
   622  		}, nil
   623  	case KeyTypeSecp256k1, KeyTypeP256:
   624  		curve := k.Type.Curve()
   625  		sig := Signature{
   626  			Type: SignatureTypeSecp256k1,
   627  		}
   628  		if k.Type == KeyTypeP256 {
   629  			sig.Type = SignatureTypeP256
   630  		}
   631  		ecKey, err := ecPrivateKeyFromBytes(k.Data, curve)
   632  		if err != nil {
   633  			return sig, err
   634  		}
   635  		sig.Data, err = ecSign(ecKey, hash)
   636  		return sig, err
   637  	case KeyTypeBls12_381:
   638  		// TODO
   639  		return Signature{}, ErrUnknownKeyType
   640  	default:
   641  		return Signature{}, ErrUnknownKeyType
   642  	}
   643  }
   644  
   645  // ParseEncryptedPrivateKey attempts to parse and optionally decrypt a
   646  // Tezos private key. When an encrypted key is detected, fn is called
   647  // and expected to return the decoding passphrase.
   648  func ParseEncryptedPrivateKey(s string, fn PassphraseFunc) (k PrivateKey, err error) {
   649  	var (
   650  		prefixLen     int = 4
   651  		shouldDecrypt bool
   652  	)
   653  	if IsEncryptedKey(s) {
   654  		prefixLen = 5
   655  		shouldDecrypt = true
   656  	}
   657  
   658  	// decode base58, version length differs between encrypted and non-encrypted keys
   659  	decoded, version, err := base58.CheckDecode(s, prefixLen, nil)
   660  	if err != nil {
   661  		if err == base58.ErrChecksum {
   662  			err = ErrChecksumMismatch
   663  			return
   664  		}
   665  		err = fmt.Errorf("tezos: unknown format for private key %s: %w", s, err)
   666  		return
   667  	}
   668  
   669  	// decrypt if necessary
   670  	if shouldDecrypt {
   671  		decoded, err = decryptPrivateKey(decoded, fn)
   672  		if err != nil {
   673  			return
   674  		}
   675  		switch {
   676  		case bytes.Equal(version, ED25519_ENCRYPTED_SEED_ID):
   677  			version = ED25519_SEED_ID
   678  		case bytes.Equal(version, SECP256K1_ENCRYPTED_SECRET_KEY_ID):
   679  			version = SECP256K1_SECRET_KEY_ID
   680  		case bytes.Equal(version, P256_ENCRYPTED_SECRET_KEY_ID):
   681  			version = P256_SECRET_KEY_ID
   682  		case bytes.Equal(version, BLS12_381_ENCRYPTED_SECRET_KEY_ID):
   683  			version = BLS12_381_SECRET_KEY_ID
   684  		}
   685  	}
   686  
   687  	// detect type
   688  	switch {
   689  	case bytes.Equal(version, ED25519_SEED_ID):
   690  		if l := len(decoded); l != ed25519.SeedSize {
   691  			return k, fmt.Errorf("tezos: invalid ed25519 seed length: %d", l)
   692  		}
   693  		k.Type = KeyTypeEd25519
   694  		// convert seed to key
   695  		decoded = []byte(ed25519.NewKeyFromSeed(decoded))
   696  	case bytes.Equal(version, ED25519_SECRET_KEY_ID):
   697  		k.Type = KeyTypeEd25519
   698  	case bytes.Equal(version, SECP256K1_SECRET_KEY_ID):
   699  		k.Type = KeyTypeSecp256k1
   700  	case bytes.Equal(version, P256_SECRET_KEY_ID):
   701  		k.Type = KeyTypeP256
   702  	case bytes.Equal(version, BLS12_381_SECRET_KEY_ID):
   703  		k.Type = KeyTypeBls12_381
   704  	default:
   705  		err = fmt.Errorf("tezos: unknown version %x for private key %s", version, s)
   706  		return
   707  	}
   708  	if l := len(decoded); l != k.Type.SkHashType().Len {
   709  		return k, fmt.Errorf("tezos: invalid length %d for %s private key data", l, k.Type.SkPrefix())
   710  	}
   711  	k.Data = decoded
   712  	return
   713  }
   714  
   715  func ParsePrivateKey(s string) (PrivateKey, error) {
   716  	return ParseEncryptedPrivateKey(s, nil)
   717  }
   718  
   719  func MustParsePrivateKey(key string) PrivateKey {
   720  	k, err := ParsePrivateKey(key)
   721  	if err != nil {
   722  		panic(err)
   723  	}
   724  	return k
   725  }
   726  
   727  // Set implements the flags.Value interface for use in command line argument parsing.
   728  func (k *PrivateKey) Set(key string) (err error) {
   729  	*k, err = ParsePrivateKey(key)
   730  	return
   731  }