github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/ed25519_private_key.go (about)

     1  package hedera
     2  
     3  /*-
     4   *
     5   * Hedera Go SDK
     6   *
     7   * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
     8   *
     9   * Licensed under the Apache License, Version 2.0 (the "License");
    10   * you may not use this file except in compliance with the License.
    11   * You may obtain a copy of the License at
    12   *
    13   *      http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing, software
    16   * distributed under the License is distributed on an "AS IS" BASIS,
    17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18   * See the License for the specific language governing permissions and
    19   * limitations under the License.
    20   *
    21   */
    22  
    23  import (
    24  	"crypto/ed25519"
    25  	"crypto/hmac"
    26  	"crypto/rand"
    27  	"crypto/sha512"
    28  	"crypto/x509/pkix"
    29  	"encoding/asn1"
    30  	"encoding/hex"
    31  	"encoding/pem"
    32  	"fmt"
    33  	"io"
    34  	"strings"
    35  
    36  	"github.com/hashgraph/hedera-protobufs-go/services"
    37  	"github.com/pkg/errors"
    38  	"github.com/youmark/pkcs8"
    39  )
    40  
    41  // _Ed25519PrivateKey is an ed25519 private key.
    42  type _Ed25519PrivateKey struct {
    43  	keyData   []byte
    44  	chainCode []byte
    45  }
    46  
    47  func _GenerateEd25519PrivateKey() (*_Ed25519PrivateKey, error) {
    48  	_, privateKey, err := ed25519.GenerateKey(rand.Reader)
    49  	if err != nil {
    50  		return &_Ed25519PrivateKey{}, err
    51  	}
    52  
    53  	return &_Ed25519PrivateKey{
    54  		keyData: privateKey,
    55  	}, nil
    56  }
    57  
    58  // Deprecated
    59  func GeneratePrivateKey() (PrivateKey, error) {
    60  	_, privateKey, err := ed25519.GenerateKey(rand.Reader)
    61  	if err != nil {
    62  		return PrivateKey{}, err
    63  	}
    64  
    65  	return PrivateKey{
    66  		ed25519PrivateKey: &_Ed25519PrivateKey{
    67  			keyData: privateKey,
    68  		},
    69  	}, nil
    70  }
    71  
    72  // _Ed25519PrivateKeyFromBytes constructs an _Ed25519PrivateKey from a raw slice of either 32 or 64 bytes.
    73  func _Ed25519PrivateKeyFromBytes(bytes []byte) (*_Ed25519PrivateKey, error) {
    74  	length := len(bytes)
    75  	switch length {
    76  	case 48:
    77  		return _Ed25519PrivateKeyFromBytesDer(bytes)
    78  	case 32:
    79  		return _Ed25519PrivateKeyFromBytesRaw(bytes)
    80  	case 64:
    81  		return _Ed25519PrivateKeyFromBytesRaw(bytes)
    82  	default:
    83  		return &_Ed25519PrivateKey{}, _NewErrBadKeyf("invalid private key length: %v bytes", len(bytes))
    84  	}
    85  }
    86  
    87  // _Ed25519PrivateKeyFromBytes constructs an _Ed25519PrivateKey from a raw slice of either 32 or 64 bytes.
    88  func _Ed25519PrivateKeyFromBytesRaw(bytes []byte) (*_Ed25519PrivateKey, error) {
    89  	return &_Ed25519PrivateKey{
    90  		keyData: ed25519.NewKeyFromSeed(bytes[0:32]),
    91  	}, nil
    92  }
    93  
    94  // _Ed25519PrivateKeyFromBytes constructs an _Ed25519PrivateKey from a raw slice of either 32 or 64 bytes.
    95  func _Ed25519PrivateKeyFromBytesDer(byt []byte) (*_Ed25519PrivateKey, error) {
    96  	given := hex.EncodeToString(byt)
    97  	result := strings.ReplaceAll(given, _Ed25519PrivateKeyPrefix, "")
    98  	decoded, err := hex.DecodeString(result)
    99  	if err != nil {
   100  		return &_Ed25519PrivateKey{}, err
   101  	}
   102  
   103  	length := len(decoded)
   104  	if length != 32 && length != 64 {
   105  		return &_Ed25519PrivateKey{}, _NewErrBadKeyf("invalid private key length: %v byt", len(byt))
   106  	}
   107  
   108  	return &_Ed25519PrivateKey{
   109  		keyData: ed25519.NewKeyFromSeed(decoded[0:32]),
   110  	}, nil
   111  }
   112  
   113  func _Ed25519PrivateKeyFromSeed(seed []byte) (*_Ed25519PrivateKey, error) {
   114  	h := hmac.New(sha512.New, []byte("ed25519 seed"))
   115  
   116  	_, err := h.Write(seed)
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	digest := h.Sum(nil)
   122  
   123  	keyBytes := digest[0:32]
   124  	chainCode := digest[32:]
   125  	privateKey, err := _Ed25519PrivateKeyFromBytes(keyBytes)
   126  
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  	privateKey.chainCode = chainCode
   131  
   132  	return privateKey, nil
   133  }
   134  
   135  // Deprecated
   136  // PrivateKeyFromMnemonic recovers an _Ed25519PrivateKey from a valid 24 word length mnemonic phrase and a
   137  // passphrase.
   138  //
   139  // An empty string can be passed for passPhrase If the mnemonic phrase wasn't generated with a passphrase. This is
   140  // required to recover a private key from a mnemonic generated by the Android and iOS wallets.
   141  func _Ed25519PrivateKeyFromMnemonic(mnemonic Mnemonic, passPhrase string) (*_Ed25519PrivateKey, error) {
   142  	seed := mnemonic._ToSeed(passPhrase)
   143  	keyFromSeed, err := _Ed25519PrivateKeyFromSeed(seed)
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	keyBytes := keyFromSeed.keyData
   149  	chainCode := keyFromSeed.chainCode
   150  
   151  	// note the index is for derivation, not the index of the slice
   152  	for _, index := range []uint32{44, 3030, 0, 0} {
   153  		keyBytes, chainCode, err = _DeriveEd25519ChildKey(keyBytes, chainCode, index)
   154  		if err != nil {
   155  			return nil, err
   156  		}
   157  	}
   158  
   159  	privateKey, err := _Ed25519PrivateKeyFromBytes(keyBytes)
   160  
   161  	if err != nil {
   162  		return nil, err
   163  	}
   164  
   165  	privateKey.chainCode = chainCode
   166  
   167  	return privateKey, nil
   168  }
   169  
   170  func _Ed25519PrivateKeyFromString(s string) (*_Ed25519PrivateKey, error) {
   171  	bytes, err := hex.DecodeString(strings.ToLower(s))
   172  	if err != nil {
   173  		return &_Ed25519PrivateKey{}, err
   174  	}
   175  
   176  	return _Ed25519PrivateKeyFromBytes(bytes)
   177  }
   178  
   179  // PrivateKeyFromKeystore recovers an _Ed25519PrivateKey from an encrypted _Keystore encoded as a byte slice.
   180  func _Ed25519PrivateKeyFromKeystore(ks []byte, passphrase string) (*_Ed25519PrivateKey, error) {
   181  	key, err := _ParseKeystore(ks, passphrase)
   182  	if err != nil {
   183  		return &_Ed25519PrivateKey{}, err
   184  	}
   185  
   186  	if key.ed25519PrivateKey != nil {
   187  		return key.ed25519PrivateKey, nil
   188  	}
   189  
   190  	return &_Ed25519PrivateKey{}, errors.New("only ed25519 keys are currently supported")
   191  }
   192  
   193  // PrivateKeyReadKeystore recovers an _Ed25519PrivateKey from an encrypted _Keystore file.
   194  func _Ed25519PrivateKeyReadKeystore(source io.Reader, passphrase string) (*_Ed25519PrivateKey, error) {
   195  	keystoreBytes, err := io.ReadAll(source)
   196  	if err != nil {
   197  		return &_Ed25519PrivateKey{}, err
   198  	}
   199  
   200  	return _Ed25519PrivateKeyFromKeystore(keystoreBytes, passphrase)
   201  }
   202  
   203  func _Ed25519PrivateKeyFromPem(bytes []byte, passphrase string) (*_Ed25519PrivateKey, error) {
   204  	var blockType string
   205  
   206  	if len(passphrase) == 0 {
   207  		blockType = "PRIVATE KEY"
   208  	} else {
   209  		// the pem is encrypted
   210  		blockType = "ENCRYPTED PRIVATE KEY"
   211  	}
   212  
   213  	var pk *pem.Block
   214  	for block, rest := pem.Decode(bytes); block != nil; {
   215  		if block.Type == blockType {
   216  			pk = block
   217  			break
   218  		}
   219  
   220  		bytes = rest
   221  		if len(bytes) == 0 {
   222  			// no key was found
   223  			return &_Ed25519PrivateKey{}, _NewErrBadKeyf("pem file did not contain a private key")
   224  		}
   225  	}
   226  
   227  	if pk == nil {
   228  		// no key was found
   229  		return &_Ed25519PrivateKey{}, _NewErrBadKeyf("no PEM data is found")
   230  	}
   231  
   232  	if len(passphrase) == 0 {
   233  		// key does not need decrypted, end here
   234  		key, err := PrivateKeyFromString(hex.EncodeToString(pk.Bytes))
   235  		if err != nil {
   236  			return &_Ed25519PrivateKey{}, err
   237  		}
   238  		return key.ed25519PrivateKey, nil
   239  	}
   240  
   241  	keyI, err := pkcs8.ParsePKCS8PrivateKey(pk.Bytes, []byte(passphrase))
   242  	if err != nil {
   243  		return &_Ed25519PrivateKey{}, err
   244  	}
   245  
   246  	return _Ed25519PrivateKeyFromBytes(keyI.(ed25519.PrivateKey))
   247  }
   248  
   249  func _Ed25519PrivateKeyReadPem(source io.Reader, passphrase string) (*_Ed25519PrivateKey, error) {
   250  	// note: Passphrases are currently not supported, but included in the function definition to avoid breaking
   251  	// changes in the future.
   252  
   253  	pemFileBytes, err := io.ReadAll(source)
   254  	if err != nil {
   255  		return &_Ed25519PrivateKey{}, err
   256  	}
   257  
   258  	return _Ed25519PrivateKeyFromPem(pemFileBytes, passphrase)
   259  }
   260  
   261  // _Ed25519PublicKey returns the _Ed25519PublicKey associated with this _Ed25519PrivateKey.
   262  func (sk _Ed25519PrivateKey) _PublicKey() *_Ed25519PublicKey {
   263  	return &_Ed25519PublicKey{
   264  		keyData: sk.keyData[32:],
   265  	}
   266  }
   267  
   268  // String returns the text-encoded representation of the _Ed25519PrivateKey.
   269  func (sk _Ed25519PrivateKey) String() string {
   270  	return sk._StringRaw()
   271  }
   272  
   273  // String returns the text-encoded representation of the _Ed25519PrivateKey.
   274  func (sk _Ed25519PrivateKey) _StringDer() string {
   275  	return fmt.Sprint(_Ed25519PrivateKeyPrefix, hex.EncodeToString(sk.keyData[:32]))
   276  }
   277  
   278  // String returns the text-encoded representation of the _Ed25519PrivateKey.
   279  func (sk _Ed25519PrivateKey) _StringRaw() string {
   280  	return hex.EncodeToString(sk.keyData[:32])
   281  }
   282  
   283  // _BytesRaw returns the byte slice representation of the _Ed25519PrivateKey.
   284  func (sk _Ed25519PrivateKey) _BytesRaw() []byte {
   285  	return sk.keyData[0:32]
   286  }
   287  
   288  func (sk _Ed25519PrivateKey) _BytesDer() []byte {
   289  	type PrivateKeyInfo struct {
   290  		Version             int
   291  		PrivateKeyAlgorithm pkix.AlgorithmIdentifier
   292  		PrivateKey          asn1.RawValue
   293  	}
   294  
   295  	// AlgorithmIdentifier for Ed25519 keys
   296  	ed25519OID := asn1.ObjectIdentifier{1, 3, 101, 112}
   297  	privateKeyBytes, err := asn1.Marshal(sk.keyData[:32])
   298  	if err != nil {
   299  		return nil
   300  	}
   301  	privateKeyInfo := PrivateKeyInfo{
   302  		Version: 0,
   303  		PrivateKeyAlgorithm: pkix.AlgorithmIdentifier{
   304  			Algorithm: ed25519OID,
   305  		},
   306  		PrivateKey: asn1.RawValue{
   307  			Tag:   asn1.TagOctetString,
   308  			Class: asn1.ClassUniversal,
   309  			Bytes: privateKeyBytes,
   310  		},
   311  	}
   312  
   313  	derBytes, err := asn1.Marshal(privateKeyInfo)
   314  	if err != nil {
   315  		return nil
   316  	}
   317  
   318  	return derBytes
   319  }
   320  
   321  // Keystore returns an encrypted _Keystore containing the _Ed25519PrivateKey.
   322  func (sk _Ed25519PrivateKey) _Keystore(passphrase string) ([]byte, error) {
   323  	return _NewKeystore(sk.keyData, passphrase)
   324  }
   325  
   326  // WriteKeystore writes an encrypted _Keystore containing the _Ed25519PrivateKey to the provided destination.
   327  func (sk _Ed25519PrivateKey) _WriteKeystore(destination io.Writer, passphrase string) error {
   328  	keystore, err := sk._Keystore(passphrase)
   329  	if err != nil {
   330  		return err
   331  	}
   332  
   333  	_, err = destination.Write(keystore)
   334  
   335  	return err
   336  }
   337  
   338  // Sign signs the provided message with the _Ed25519PrivateKey.
   339  func (sk _Ed25519PrivateKey) _Sign(message []byte) []byte {
   340  	return ed25519.Sign(sk.keyData, message)
   341  }
   342  
   343  // SupportsDerivation returns true if the _Ed25519PrivateKey supports derivation.
   344  func (sk _Ed25519PrivateKey) _SupportsDerivation() bool {
   345  	return sk.chainCode != nil
   346  }
   347  
   348  // Derive a child key compatible with the iOS and Android wallets using a provided wallet/account index. Use index 0 for
   349  // the default account.
   350  //
   351  // This will fail if the key does not support derivation which can be checked by calling SupportsDerivation()
   352  func (sk _Ed25519PrivateKey) _Derive(index uint32) (*_Ed25519PrivateKey, error) {
   353  	if !sk._SupportsDerivation() {
   354  		return nil, _NewErrBadKeyf("child key cannot be derived from this key")
   355  	}
   356  
   357  	derivedKeyBytes, chainCode, err := _DeriveEd25519ChildKey(sk._BytesRaw(), sk.chainCode, index)
   358  	if err != nil {
   359  		return nil, err
   360  	}
   361  
   362  	derivedKey, err := _Ed25519PrivateKeyFromBytes(derivedKeyBytes)
   363  
   364  	if err != nil {
   365  		return nil, err
   366  	}
   367  
   368  	derivedKey.chainCode = chainCode
   369  
   370  	return derivedKey, nil
   371  }
   372  
   373  func (sk _Ed25519PrivateKey) _LegacyDerive(index int64) (*_Ed25519PrivateKey, error) {
   374  	keyData, err := _DeriveLegacyChildKey(sk._BytesRaw(), index)
   375  	if err != nil {
   376  		return nil, err
   377  	}
   378  
   379  	return _Ed25519PrivateKeyFromBytes(keyData)
   380  }
   381  
   382  func (sk _Ed25519PrivateKey) _ToProtoKey() *services.Key {
   383  	return sk._PublicKey()._ToProtoKey()
   384  }
   385  
   386  func (sk _Ed25519PrivateKey) _SignTransaction(tx *Transaction) ([]byte, error) {
   387  	tx._RequireOneNodeAccountID()
   388  
   389  	if tx.signedTransactions._Length() == 0 {
   390  		return make([]byte, 0), errTransactionRequiresSingleNodeAccountID
   391  	}
   392  
   393  	signature := sk._Sign(tx.signedTransactions._Get(0).(*services.SignedTransaction).GetBodyBytes())
   394  
   395  	publicKey := sk._PublicKey()
   396  	if publicKey == nil {
   397  		return []byte{}, errors.New("public key is nil")
   398  	}
   399  
   400  	wrappedPublicKey := PublicKey{
   401  		ed25519PublicKey: publicKey,
   402  	}
   403  
   404  	if tx._KeyAlreadySigned(wrappedPublicKey) {
   405  		return []byte{}, nil
   406  	}
   407  
   408  	tx.transactions = _NewLockableSlice()
   409  	tx.publicKeys = append(tx.publicKeys, wrappedPublicKey)
   410  	tx.transactionSigners = append(tx.transactionSigners, nil)
   411  	tx.transactionIDs.locked = true
   412  
   413  	for index := 0; index < tx.signedTransactions._Length(); index++ {
   414  		temp := tx.signedTransactions._Get(index).(*services.SignedTransaction)
   415  		temp.SigMap.SigPair = append(
   416  			temp.SigMap.SigPair,
   417  			publicKey._ToSignaturePairProtobuf(signature),
   418  		)
   419  		tx.signedTransactions._Set(index, temp)
   420  	}
   421  
   422  	return signature, nil
   423  }