gitlab.com/yannislg/go-pulse@v0.0.0-20210722055913-a3e24e95638d/crypto/crypto.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package crypto
    18  
    19  import (
    20  	"bufio"
    21  	"crypto/ecdsa"
    22  	"crypto/elliptic"
    23  	"crypto/rand"
    24  	"encoding/hex"
    25  	"errors"
    26  	"fmt"
    27  	"io"
    28  	"io/ioutil"
    29  	"math/big"
    30  	"os"
    31  
    32  	"github.com/ethereum/go-ethereum/common"
    33  	"github.com/ethereum/go-ethereum/common/math"
    34  	"github.com/ethereum/go-ethereum/rlp"
    35  	"golang.org/x/crypto/sha3"
    36  )
    37  
    38  //SignatureLength indicates the byte length required to carry a signature with recovery id.
    39  const SignatureLength = 64 + 1 // 64 bytes ECDSA signature + 1 byte recovery id
    40  
    41  // RecoveryIDOffset points to the byte offset within the signature that contains the recovery id.
    42  const RecoveryIDOffset = 64
    43  
    44  // DigestLength sets the signature digest exact length
    45  const DigestLength = 32
    46  
    47  var (
    48  	secp256k1N, _  = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
    49  	secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
    50  )
    51  
    52  var errInvalidPubkey = errors.New("invalid secp256k1 public key")
    53  
    54  // Keccak256 calculates and returns the Keccak256 hash of the input data.
    55  func Keccak256(data ...[]byte) []byte {
    56  	d := sha3.NewLegacyKeccak256()
    57  	for _, b := range data {
    58  		d.Write(b)
    59  	}
    60  	return d.Sum(nil)
    61  }
    62  
    63  // Keccak256Hash calculates and returns the Keccak256 hash of the input data,
    64  // converting it to an internal Hash data structure.
    65  func Keccak256Hash(data ...[]byte) (h common.Hash) {
    66  	d := sha3.NewLegacyKeccak256()
    67  	for _, b := range data {
    68  		d.Write(b)
    69  	}
    70  	d.Sum(h[:0])
    71  	return h
    72  }
    73  
    74  // Keccak512 calculates and returns the Keccak512 hash of the input data.
    75  func Keccak512(data ...[]byte) []byte {
    76  	d := sha3.NewLegacyKeccak512()
    77  	for _, b := range data {
    78  		d.Write(b)
    79  	}
    80  	return d.Sum(nil)
    81  }
    82  
    83  // CreateAddress creates an ethereum address given the bytes and the nonce
    84  func CreateAddress(b common.Address, nonce uint64) common.Address {
    85  	data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
    86  	return common.BytesToAddress(Keccak256(data)[12:])
    87  }
    88  
    89  // CreateAddress2 creates an ethereum address given the address bytes, initial
    90  // contract code hash and a salt.
    91  func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
    92  	return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
    93  }
    94  
    95  // ToECDSA creates a private key with the given D value.
    96  func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
    97  	return toECDSA(d, true)
    98  }
    99  
   100  // ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost
   101  // never be used unless you are sure the input is valid and want to avoid hitting
   102  // errors due to bad origin encoding (0 prefixes cut off).
   103  func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey {
   104  	priv, _ := toECDSA(d, false)
   105  	return priv
   106  }
   107  
   108  // toECDSA creates a private key with the given D value. The strict parameter
   109  // controls whether the key's length should be enforced at the curve size or
   110  // it can also accept legacy encodings (0 prefixes).
   111  func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
   112  	priv := new(ecdsa.PrivateKey)
   113  	priv.PublicKey.Curve = S256()
   114  	if strict && 8*len(d) != priv.Params().BitSize {
   115  		return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
   116  	}
   117  	priv.D = new(big.Int).SetBytes(d)
   118  
   119  	// The priv.D must < N
   120  	if priv.D.Cmp(secp256k1N) >= 0 {
   121  		return nil, fmt.Errorf("invalid private key, >=N")
   122  	}
   123  	// The priv.D must not be zero or negative.
   124  	if priv.D.Sign() <= 0 {
   125  		return nil, fmt.Errorf("invalid private key, zero or negative")
   126  	}
   127  
   128  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
   129  	if priv.PublicKey.X == nil {
   130  		return nil, errors.New("invalid private key")
   131  	}
   132  	return priv, nil
   133  }
   134  
   135  // FromECDSA exports a private key into a binary dump.
   136  func FromECDSA(priv *ecdsa.PrivateKey) []byte {
   137  	if priv == nil {
   138  		return nil
   139  	}
   140  	return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
   141  }
   142  
   143  // UnmarshalPubkey converts bytes to a secp256k1 public key.
   144  func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
   145  	x, y := elliptic.Unmarshal(S256(), pub)
   146  	if x == nil {
   147  		return nil, errInvalidPubkey
   148  	}
   149  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
   150  }
   151  
   152  func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
   153  	if pub == nil || pub.X == nil || pub.Y == nil {
   154  		return nil
   155  	}
   156  	return elliptic.Marshal(S256(), pub.X, pub.Y)
   157  }
   158  
   159  // HexToECDSA parses a secp256k1 private key.
   160  func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
   161  	b, err := hex.DecodeString(hexkey)
   162  	if byteErr, ok := err.(hex.InvalidByteError); ok {
   163  		return nil, fmt.Errorf("invalid hex character %q in private key", byte(byteErr))
   164  	} else if err != nil {
   165  		return nil, errors.New("invalid hex data for private key")
   166  	}
   167  	return ToECDSA(b)
   168  }
   169  
   170  // LoadECDSA loads a secp256k1 private key from the given file.
   171  func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
   172  	fd, err := os.Open(file)
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  	defer fd.Close()
   177  
   178  	r := bufio.NewReader(fd)
   179  	buf := make([]byte, 64)
   180  	n, err := readASCII(buf, r)
   181  	if err != nil {
   182  		return nil, err
   183  	} else if n != len(buf) {
   184  		return nil, fmt.Errorf("key file too short, want 64 hex characters")
   185  	}
   186  	if err := checkKeyFileEnd(r); err != nil {
   187  		return nil, err
   188  	}
   189  
   190  	return HexToECDSA(string(buf))
   191  }
   192  
   193  // readASCII reads into 'buf', stopping when the buffer is full or
   194  // when a non-printable control character is encountered.
   195  func readASCII(buf []byte, r *bufio.Reader) (n int, err error) {
   196  	for ; n < len(buf); n++ {
   197  		buf[n], err = r.ReadByte()
   198  		switch {
   199  		case err == io.EOF || buf[n] < '!':
   200  			return n, nil
   201  		case err != nil:
   202  			return n, err
   203  		}
   204  	}
   205  	return n, nil
   206  }
   207  
   208  // checkKeyFileEnd skips over additional newlines at the end of a key file.
   209  func checkKeyFileEnd(r *bufio.Reader) error {
   210  	for i := 0; ; i++ {
   211  		b, err := r.ReadByte()
   212  		switch {
   213  		case err == io.EOF:
   214  			return nil
   215  		case err != nil:
   216  			return err
   217  		case b != '\n' && b != '\r':
   218  			return fmt.Errorf("invalid character %q at end of key file", b)
   219  		case i >= 2:
   220  			return errors.New("key file too long, want 64 hex characters")
   221  		}
   222  	}
   223  }
   224  
   225  // SaveECDSA saves a secp256k1 private key to the given file with
   226  // restrictive permissions. The key data is saved hex-encoded.
   227  func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
   228  	k := hex.EncodeToString(FromECDSA(key))
   229  	return ioutil.WriteFile(file, []byte(k), 0600)
   230  }
   231  
   232  // GenerateKey generates a new private key.
   233  func GenerateKey() (*ecdsa.PrivateKey, error) {
   234  	return ecdsa.GenerateKey(S256(), rand.Reader)
   235  }
   236  
   237  // ValidateSignatureValues verifies whether the signature values are valid with
   238  // the given chain rules. The v value is assumed to be either 0 or 1.
   239  func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool {
   240  	if r.Cmp(common.Big1) < 0 || s.Cmp(common.Big1) < 0 {
   241  		return false
   242  	}
   243  	// reject upper range of s values (ECDSA malleability)
   244  	// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
   245  	if homestead && s.Cmp(secp256k1halfN) > 0 {
   246  		return false
   247  	}
   248  	// Frontier: allow s to be in full N range
   249  	return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1)
   250  }
   251  
   252  func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
   253  	pubBytes := FromECDSAPub(&p)
   254  	return common.BytesToAddress(Keccak256(pubBytes[1:])[12:])
   255  }
   256  
   257  func zeroBytes(bytes []byte) {
   258  	for i := range bytes {
   259  		bytes[i] = 0
   260  	}
   261  }