github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/utilities/crypto/crypto.go (about)

     1  package crypto
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/elliptic"
     6  	"crypto/rand"
     7  
     8  	"encoding/hex"
     9  	"errors"
    10  	"fmt"
    11  
    12  	"io"
    13  	"io/ioutil"
    14  	"math/big"
    15  	"os"
    16  
    17  	"github.com/neatlab/neatio/utilities/common"
    18  	"github.com/neatlab/neatio/utilities/common/math"
    19  	"github.com/neatlab/neatio/utilities/rlp"
    20  
    21  	"golang.org/x/crypto/sha3"
    22  )
    23  
    24  var (
    25  	secp256k1N, _  = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
    26  	secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
    27  )
    28  
    29  var errInvalidPubkey = errors.New("invalid secp256k1 public key")
    30  
    31  func Keccak256(data ...[]byte) []byte {
    32  	d := sha3.NewLegacyKeccak256()
    33  	for _, b := range data {
    34  		d.Write(b)
    35  	}
    36  	return d.Sum(nil)
    37  }
    38  
    39  func Keccak256Hash(data ...[]byte) (h common.Hash) {
    40  	d := sha3.NewLegacyKeccak256()
    41  	for _, b := range data {
    42  		d.Write(b)
    43  	}
    44  	d.Sum(h[:0])
    45  	return h
    46  }
    47  
    48  func Keccak512(data ...[]byte) []byte {
    49  	d := sha3.NewLegacyKeccak512()
    50  	for _, b := range data {
    51  		d.Write(b)
    52  	}
    53  	return d.Sum(nil)
    54  }
    55  
    56  func CreateAddress(b common.Address, nonce uint64) common.Address {
    57  	data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
    58  	return common.BytesToAddress(Keccak256(data)[12:])
    59  }
    60  
    61  func CreateAddress2(b common.Address, salt [32]byte, initHash []byte) common.Address {
    62  	return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], initHash)[12:])
    63  }
    64  
    65  func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
    66  	return toECDSA(d, true)
    67  }
    68  
    69  func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey {
    70  	priv, _ := toECDSA(d, false)
    71  	return priv
    72  }
    73  
    74  func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
    75  	priv := new(ecdsa.PrivateKey)
    76  	priv.PublicKey.Curve = S256()
    77  	if strict && 8*len(d) != priv.Params().BitSize {
    78  		return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
    79  	}
    80  	priv.D = new(big.Int).SetBytes(d)
    81  
    82  	if priv.D.Cmp(secp256k1N) >= 0 {
    83  		return nil, fmt.Errorf("invalid private key, >=N")
    84  	}
    85  
    86  	if priv.D.Sign() <= 0 {
    87  		return nil, fmt.Errorf("invalid private key, zero or negative")
    88  	}
    89  
    90  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
    91  	if priv.PublicKey.X == nil {
    92  		return nil, errors.New("invalid private key")
    93  	}
    94  	return priv, nil
    95  }
    96  
    97  func FromECDSA(priv *ecdsa.PrivateKey) []byte {
    98  	if priv == nil {
    99  		return nil
   100  	}
   101  	return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
   102  }
   103  
   104  func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
   105  	if len(pub) == 0 {
   106  		return nil
   107  	}
   108  	x, y := elliptic.Unmarshal(S256(), pub)
   109  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}
   110  }
   111  
   112  func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
   113  	x, y := elliptic.Unmarshal(S256(), pub)
   114  	if x == nil {
   115  		return nil, errInvalidPubkey
   116  	}
   117  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
   118  }
   119  
   120  func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
   121  	if pub == nil || pub.X == nil || pub.Y == nil {
   122  		return nil
   123  	}
   124  	return elliptic.Marshal(S256(), pub.X, pub.Y)
   125  }
   126  
   127  func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
   128  	b, err := hex.DecodeString(hexkey)
   129  	if err != nil {
   130  		return nil, errors.New("invalid hex string")
   131  	}
   132  	return ToECDSA(b)
   133  }
   134  
   135  func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
   136  	buf := make([]byte, 64)
   137  	fd, err := os.Open(file)
   138  	if err != nil {
   139  		return nil, err
   140  	}
   141  	defer fd.Close()
   142  	if _, err := io.ReadFull(fd, buf); err != nil {
   143  		return nil, err
   144  	}
   145  
   146  	key, err := hex.DecodeString(string(buf))
   147  	if err != nil {
   148  		return nil, err
   149  	}
   150  	return ToECDSA(key)
   151  }
   152  
   153  func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
   154  	k := hex.EncodeToString(FromECDSA(key))
   155  	return ioutil.WriteFile(file, []byte(k), 0600)
   156  }
   157  
   158  func GenerateKey() (*ecdsa.PrivateKey, error) {
   159  	return ecdsa.GenerateKey(S256(), rand.Reader)
   160  }
   161  
   162  func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool {
   163  	if r.Cmp(common.Big1) < 0 || s.Cmp(common.Big1) < 0 {
   164  		return false
   165  	}
   166  
   167  	if homestead && s.Cmp(secp256k1halfN) > 0 {
   168  		return false
   169  	}
   170  
   171  	return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1)
   172  }
   173  
   174  func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
   175  	pubBytes := FromECDSAPub(&p)
   176  	return common.BytesToAddress(Keccak256(pubBytes[1:])[12:])
   177  }
   178  
   179  func zeroBytes(bytes []byte) {
   180  	for i := range bytes {
   181  		bytes[i] = 0
   182  	}
   183  }