github.com/aquanetwork/aquachain@v1.7.8/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  	"bytes"
    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  	"gitlab.com/aquachain/aquachain/common"
    33  	"gitlab.com/aquachain/aquachain/common/math"
    34  	"gitlab.com/aquachain/aquachain/crypto/sha3"
    35  	"gitlab.com/aquachain/aquachain/rlp"
    36  	"golang.org/x/crypto/argon2"
    37  )
    38  
    39  var (
    40  	secp256k1_N, _  = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
    41  	secp256k1_halfN = new(big.Int).Div(secp256k1_N, big.NewInt(2))
    42  )
    43  
    44  const (
    45  	argonThreads uint8  = 1
    46  	argonTime    uint32 = 1
    47  )
    48  
    49  const KnownVersion = 4
    50  
    51  // VersionHash switch version, returns digest bytes, v is not hashed.
    52  func VersionHash(v byte, data ...[]byte) []byte {
    53  	switch v {
    54  	//	case 0:
    55  	//		return Keccak256(data...)
    56  	case 1:
    57  		return Keccak256(data...)
    58  	case 2:
    59  		return Argon2idA(data...)
    60  	case 3:
    61  		return Argon2idB(data...)
    62  	case 4:
    63  		return Argon2idC(data...)
    64  	default:
    65  		panic("invalid block version")
    66  	}
    67  }
    68  
    69  // Argon2id calculates and returns the Argon2id hash of the input data, using 1kb mem
    70  func Argon2idA(data ...[]byte) []byte {
    71  	//fmt.Printf(".")
    72  	buf := &bytes.Buffer{}
    73  	for i := range data {
    74  		buf.Write(data[i])
    75  	}
    76  	return argon2.IDKey(buf.Bytes(), nil, argonTime, 1, argonThreads, common.HashLength)
    77  }
    78  
    79  // Argon2id calculates and returns the Argon2id hash of the input data, using 16kb mem
    80  func Argon2idB(data ...[]byte) []byte {
    81  	//fmt.Printf(".")
    82  	buf := &bytes.Buffer{}
    83  	for i := range data {
    84  		buf.Write(data[i])
    85  	}
    86  	return argon2.IDKey(buf.Bytes(), nil, argonTime, 16, argonThreads, common.HashLength)
    87  }
    88  
    89  // Argon2id calculates and returns the Argon2id hash of the input data, using 32kb
    90  func Argon2idC(data ...[]byte) []byte {
    91  	//fmt.Printf(".")
    92  	buf := &bytes.Buffer{}
    93  	for i := range data {
    94  		buf.Write(data[i])
    95  	}
    96  	return argon2.IDKey(buf.Bytes(), nil, argonTime, 32, argonThreads, common.HashLength)
    97  }
    98  
    99  // Argon2id calculates and returns the Argon2id hash of the input data.
   100  func Argon2idAHash(data ...[]byte) (h common.Hash) {
   101  	return common.BytesToHash(Argon2idA(data...))
   102  }
   103  
   104  // Argon2id calculates and returns the Argon2id hash of the input data.
   105  func Argon2idBHash(data ...[]byte) (h common.Hash) {
   106  	return common.BytesToHash(Argon2idB(data...))
   107  }
   108  
   109  // Argon2id calculates and returns the Argon2id hash of the input data.
   110  func Argon2idCHash(data ...[]byte) (h common.Hash) {
   111  	return common.BytesToHash(Argon2idC(data...))
   112  }
   113  
   114  // Keccak256 calculates and returns the Keccak256 hash of the input data.
   115  func Keccak256(data ...[]byte) []byte {
   116  	//fmt.Printf("o")
   117  	d := sha3.NewKeccak256()
   118  	for _, b := range data {
   119  		d.Write(b)
   120  	}
   121  	return d.Sum(nil)
   122  }
   123  
   124  // Keccak256Hash calculates and returns the Keccak256 hash of the input data,
   125  // converting it to an internal Hash data structure.
   126  func Keccak256Hash(data ...[]byte) (h common.Hash) {
   127  	//fmt.Printf("x")
   128  	d := sha3.NewKeccak256()
   129  	for _, b := range data {
   130  		d.Write(b)
   131  	}
   132  	d.Sum(h[:0])
   133  	return h
   134  }
   135  
   136  // Keccak512 calculates and returns the Keccak512 hash of the input data.
   137  func Keccak512(data ...[]byte) []byte {
   138  	d := sha3.NewKeccak512()
   139  	for _, b := range data {
   140  		d.Write(b)
   141  	}
   142  	return d.Sum(nil)
   143  }
   144  
   145  // Creates an ethereum address given the bytes and the nonce
   146  func CreateAddress(b common.Address, nonce uint64) common.Address {
   147  	data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
   148  	return common.BytesToAddress(Keccak256(data)[12:])
   149  }
   150  
   151  // ToECDSA creates a private key with the given D value.
   152  func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
   153  	return toECDSA(d, true)
   154  }
   155  
   156  // ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost
   157  // never be used unless you are sure the input is valid and want to avoid hitting
   158  // errors due to bad origin encoding (0 prefixes cut off).
   159  func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey {
   160  	priv, _ := toECDSA(d, false)
   161  	return priv
   162  }
   163  
   164  // toECDSA creates a private key with the given D value. The strict parameter
   165  // controls whether the key's length should be enforced at the curve size or
   166  // it can also accept legacy encodings (0 prefixes).
   167  func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
   168  	priv := new(ecdsa.PrivateKey)
   169  	priv.PublicKey.Curve = S256()
   170  	if strict && 8*len(d) != priv.Params().BitSize {
   171  		return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
   172  	}
   173  	priv.D = new(big.Int).SetBytes(d)
   174  
   175  	// The priv.D must < N
   176  	if priv.D.Cmp(secp256k1_N) >= 0 {
   177  		return nil, fmt.Errorf("invalid private key, >=N")
   178  	}
   179  	// The priv.D must not be zero or negative.
   180  	if priv.D.Sign() <= 0 {
   181  		return nil, fmt.Errorf("invalid private key, zero or negative")
   182  	}
   183  
   184  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
   185  	if priv.PublicKey.X == nil {
   186  		return nil, errors.New("invalid private key")
   187  	}
   188  	return priv, nil
   189  }
   190  
   191  // FromECDSA exports a private key into a binary dump.
   192  func FromECDSA(priv *ecdsa.PrivateKey) []byte {
   193  	if priv == nil {
   194  		return nil
   195  	}
   196  	return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
   197  }
   198  
   199  func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
   200  	if len(pub) == 0 {
   201  		return nil
   202  	}
   203  	x, y := elliptic.Unmarshal(S256(), pub)
   204  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}
   205  }
   206  
   207  func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
   208  	if pub == nil || pub.X == nil || pub.Y == nil {
   209  		return nil
   210  	}
   211  	return elliptic.Marshal(S256(), pub.X, pub.Y)
   212  }
   213  
   214  // HexToECDSA parses a secp256k1 private key.
   215  func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
   216  	b, err := hex.DecodeString(hexkey)
   217  	if err != nil {
   218  		return nil, errors.New("invalid hex string")
   219  	}
   220  	return ToECDSA(b)
   221  }
   222  
   223  // LoadECDSA loads a secp256k1 private key from the given file.
   224  func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
   225  	buf := make([]byte, 64)
   226  	fd, err := os.Open(file)
   227  	if err != nil {
   228  		return nil, err
   229  	}
   230  	defer fd.Close()
   231  	if _, err := io.ReadFull(fd, buf); err != nil {
   232  		return nil, err
   233  	}
   234  
   235  	key, err := hex.DecodeString(string(buf))
   236  	if err != nil {
   237  		return nil, err
   238  	}
   239  	return ToECDSA(key)
   240  }
   241  
   242  // SaveECDSA saves a secp256k1 private key to the given file with
   243  // restrictive permissions. The key data is saved hex-encoded.
   244  func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
   245  	k := hex.EncodeToString(FromECDSA(key))
   246  	return ioutil.WriteFile(file, []byte(k), 0600)
   247  }
   248  
   249  func GenerateKey() (*ecdsa.PrivateKey, error) {
   250  	return ecdsa.GenerateKey(S256(), rand.Reader)
   251  }
   252  
   253  // ValidateSignatureValues verifies whether the signature values are valid with
   254  // the given chain rules. The v value is assumed to be either 0 or 1.
   255  func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool {
   256  	if r.Cmp(common.Big1) < 0 || s.Cmp(common.Big1) < 0 {
   257  		return false
   258  	}
   259  	// reject upper range of s values (ECDSA malleability)
   260  	// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
   261  	if homestead && s.Cmp(secp256k1_halfN) > 0 {
   262  		return false
   263  	}
   264  	// Frontier: allow s to be in full N range
   265  	return r.Cmp(secp256k1_N) < 0 && s.Cmp(secp256k1_N) < 0 && (v == 0 || v == 1)
   266  }
   267  
   268  func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
   269  	pubBytes := FromECDSAPub(&p)
   270  	return common.BytesToAddress(Keccak256(pubBytes[1:])[12:])
   271  }
   272  
   273  func zeroBytes(bytes []byte) {
   274  	for i := range bytes {
   275  		bytes[i] = 0
   276  	}
   277  }