github.com/klaytn/klaytn@v1.12.1/accounts/keystore/key2335.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // Modified by Prysmatic Labs 2018
     5  // Modified by the klaytn Authors 2023
     6  //
     7  // The go-ethereum library is free software: you can redistribute it and/or modify
     8  // it under the terms of the GNU Lesser General Public License as published by
     9  // the Free Software Foundation, either version 3 of the License, or
    10  // (at your option) any later version.
    11  //
    12  // The go-ethereum library is distributed in the hope that it will be useful,
    13  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  // GNU Lesser General Public License for more details.
    16  //
    17  // You should have received a copy of the GNU Lesser General Public License
    18  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    19  
    20  package keystore
    21  
    22  import (
    23  	"encoding/hex"
    24  	"encoding/json"
    25  	"errors"
    26  
    27  	"github.com/klaytn/klaytn/crypto/bls"
    28  	"github.com/pborman/uuid"
    29  	keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
    30  )
    31  
    32  // KeyEIP2335 is a decrypted BLS12-381 keypair.
    33  type KeyEIP2335 struct {
    34  	ID uuid.UUID // Version 4 "random" for unique id not derived from key data
    35  
    36  	PublicKey bls.PublicKey // Represents the public key of the user.
    37  	SecretKey bls.SecretKey // Represents the private key of the user.
    38  }
    39  
    40  // https://eips.ethereum.org/EIPS/eip-2335
    41  // Required fields: crypto, path, uuid, version
    42  type encryptedKeyEIP2335JSON struct {
    43  	Crypto      map[string]interface{} `json:"crypto"`
    44  	Description string                 `json:"description"`
    45  	Pubkey      string                 `json:"pubkey"`
    46  	Path        string                 `json:"path"`
    47  	ID          string                 `json:"uuid"`
    48  	Version     int                    `json:"version"`
    49  }
    50  
    51  // NewKeyEIP2335 creates a new EIP-2335 keystore Key type using a BLS private key.
    52  func NewKeyEIP2335(blsKey bls.SecretKey) *KeyEIP2335 {
    53  	return &KeyEIP2335{
    54  		ID:        uuid.NewRandom(),
    55  		PublicKey: blsKey.PublicKey(),
    56  		SecretKey: blsKey,
    57  	}
    58  }
    59  
    60  // DecryptKeyEIP2335 decrypts a key from an EIP-2335 JSON blob, returning the BLS private key.
    61  func DecryptKeyEIP2335(keyJSON []byte, password string) (*KeyEIP2335, error) {
    62  	k := new(encryptedKeyEIP2335JSON)
    63  	if err := json.Unmarshal(keyJSON, k); err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	id := uuid.Parse(k.ID)
    68  	if id == nil {
    69  		return nil, errors.New("Invalid UUID")
    70  	}
    71  
    72  	decryptor := keystorev4.New()
    73  	keyBytes, err := decryptor.Decrypt(k.Crypto, password)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	secretKey, err := bls.SecretKeyFromBytes(keyBytes)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	return &KeyEIP2335{
    84  		ID:        id,
    85  		PublicKey: secretKey.PublicKey(),
    86  		SecretKey: secretKey,
    87  	}, nil
    88  }
    89  
    90  // EncryptKeyEIP2335 encrypts a BLS key using the specified scrypt parameters into a JSON
    91  // blob that can be decrypted later on.
    92  func EncryptKeyEIP2335(key *KeyEIP2335, password string, scryptN, scryptP int) ([]byte, error) {
    93  	keyBytes := key.SecretKey.Marshal()
    94  	encryptor := keystorev4.New()
    95  	cryptoObj, err := encryptor.Encrypt(keyBytes, password)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	encryptedJSON := encryptedKeyEIP2335JSON{
   101  		Crypto:      cryptoObj,
   102  		Description: "",
   103  		Pubkey:      hex.EncodeToString(key.PublicKey.Marshal()),
   104  		Path:        "", // EIP-2335: if no path is known or the path is not relevant, the empty string, "" indicates this
   105  		ID:          key.ID.String(),
   106  		Version:     4,
   107  	}
   108  	return json.Marshal(encryptedJSON)
   109  }