github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/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/hmac"
    24  	"crypto/rand"
    25  	"crypto/sha1"
    26  	"crypto/sha512"
    27  	"encoding/hex"
    28  	"errors"
    29  	"fmt"
    30  	"hash"
    31  	"io"
    32  	"io/ioutil"
    33  	"math/big"
    34  	"os"
    35  	"strings"
    36  
    37  	sha256 "github.com/minio/sha256-simd"
    38  	"github.com/vntchain/go-vnt/common"
    39  	"github.com/vntchain/go-vnt/common/math"
    40  	"github.com/vntchain/go-vnt/crypto/sha3"
    41  	"github.com/vntchain/go-vnt/rlp"
    42  )
    43  
    44  var (
    45  	secp256k1N, _  = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
    46  	secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
    47  )
    48  
    49  var errInvalidPubkey = errors.New("invalid secp256k1 public key")
    50  
    51  // Keccak256 calculates and returns the Keccak256 hash of the input data.
    52  func Keccak256(data ...[]byte) []byte {
    53  	d := sha3.NewKeccak256()
    54  	for _, b := range data {
    55  		d.Write(b)
    56  	}
    57  	return d.Sum(nil)
    58  }
    59  
    60  // Keccak256Hash calculates and returns the Keccak256 hash of the input data,
    61  // converting it to an internal Hash data structure.
    62  func Keccak256Hash(data ...[]byte) (h common.Hash) {
    63  	d := sha3.NewKeccak256()
    64  	for _, b := range data {
    65  		d.Write(b)
    66  	}
    67  	d.Sum(h[:0])
    68  	return h
    69  }
    70  
    71  // Keccak512 calculates and returns the Keccak512 hash of the input data.
    72  func Keccak512(data ...[]byte) []byte {
    73  	d := sha3.NewKeccak512()
    74  	for _, b := range data {
    75  		d.Write(b)
    76  	}
    77  	return d.Sum(nil)
    78  }
    79  
    80  // CreateAddress creates an hubble address given the bytes and the nonce
    81  func CreateAddress(b common.Address, nonce uint64) common.Address {
    82  	data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
    83  	return common.BytesToAddress(Keccak256(data)[12:])
    84  }
    85  
    86  // ToECDSA creates a private key with the given D value.
    87  func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
    88  	return toECDSA(d, true)
    89  }
    90  
    91  // ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost
    92  // never be used unless you are sure the input is valid and want to avoid hitting
    93  // errors due to bad origin encoding (0 prefixes cut off).
    94  func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey {
    95  	priv, _ := toECDSA(d, false)
    96  	return priv
    97  }
    98  
    99  // toECDSA creates a private key with the given D value. The strict parameter
   100  // controls whether the key's length should be enforced at the curve size or
   101  // it can also accept legacy encodings (0 prefixes).
   102  func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
   103  	priv := new(ecdsa.PrivateKey)
   104  	priv.PublicKey.Curve = S256()
   105  	if strict && 8*len(d) != priv.Params().BitSize {
   106  		return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
   107  	}
   108  	priv.D = new(big.Int).SetBytes(d)
   109  
   110  	// The priv.D must < N
   111  	if priv.D.Cmp(secp256k1N) >= 0 {
   112  		return nil, fmt.Errorf("invalid private key, >=N")
   113  	}
   114  	// The priv.D must not be zero or negative.
   115  	if priv.D.Sign() <= 0 {
   116  		return nil, fmt.Errorf("invalid private key, zero or negative")
   117  	}
   118  
   119  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
   120  	if priv.PublicKey.X == nil {
   121  		return nil, errors.New("invalid private key")
   122  	}
   123  	return priv, nil
   124  }
   125  
   126  // FromECDSA exports a private key into a binary dump.
   127  func FromECDSA(priv *ecdsa.PrivateKey) []byte {
   128  	if priv == nil {
   129  		return nil
   130  	}
   131  	return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
   132  }
   133  
   134  // UnmarshalPubkey converts bytes to a secp256k1 public key.
   135  func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
   136  	x, y := elliptic.Unmarshal(S256(), pub)
   137  	if x == nil {
   138  		return nil, errInvalidPubkey
   139  	}
   140  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
   141  }
   142  
   143  func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
   144  	if pub == nil || pub.X == nil || pub.Y == nil {
   145  		return nil
   146  	}
   147  	return elliptic.Marshal(S256(), pub.X, pub.Y)
   148  }
   149  
   150  // HexToECDSA parses a secp256k1 private key.
   151  func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
   152  	b, err := hex.DecodeString(hexkey)
   153  	if err != nil {
   154  		return nil, errors.New("invalid hex string")
   155  	}
   156  	return ToECDSA(b)
   157  }
   158  
   159  // LoadECDSA loads a secp256k1 private key from the given file.
   160  func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
   161  	buf := make([]byte, 64)
   162  	fd, err := os.Open(file)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  	defer fd.Close()
   167  	if _, err := io.ReadFull(fd, buf); err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	key, err := hex.DecodeString(string(buf))
   172  	if err != nil {
   173  		return nil, err
   174  	}
   175  	return ToECDSA(key)
   176  }
   177  
   178  // SaveECDSA saves a secp256k1 private key to the given file with
   179  // restrictive permissions. The key data is saved hex-encoded.
   180  func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
   181  	k := hex.EncodeToString(FromECDSA(key))
   182  	return ioutil.WriteFile(file, []byte(k), 0600)
   183  }
   184  
   185  // === BEGIN ====P
   186  // 目前看来是不必要的
   187  // func GetPublicKeyFromByte(bkey []byte) (*ecdsa.PublicKey, error) {
   188  // 	pk, err := x509.ParsePKIXPublicKey(bkey)
   189  // 	if err != nil {
   190  // 		return nil, err
   191  // 	}
   192  // 	var pubkey *ecdsa.PublicKey
   193  
   194  // 	switch pk.(type) {
   195  // 	case *ecdsa.PublicKey:
   196  // 		pubkey = pk.(*ecdsa.PublicKey)
   197  // 	default:
   198  // 		return nil, fmt.Errorf("PublicKey type error")
   199  // 	}
   200  
   201  // 	return pubkey, nil
   202  // }
   203  
   204  func GenerateKeyByWord(key string) (*ecdsa.PrivateKey, error) {
   205  	length := len([]byte(key))
   206  
   207  	var curve elliptic.Curve
   208  
   209  	if length >= 256/8+8 && length < 384/8+8 {
   210  		curve = S256()
   211  	} else {
   212  		panic("length is not enough")
   213  	}
   214  
   215  	return ecdsa.GenerateKey(curve, strings.NewReader(key))
   216  }
   217  
   218  type GenSharedKey func([]byte) ([]byte, error)
   219  
   220  func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
   221  	var curve elliptic.Curve
   222  
   223  	// switch curveName {
   224  	// case "P-256":
   225  	// 	curve = elliptic.P256()
   226  	// case "P-384":
   227  	// 	curve = elliptic.P384()
   228  	// case "P-521":
   229  	// 	curve = elliptic.P521()
   230  	// }
   231  	curve = S256()
   232  
   233  	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
   234  	if err != nil {
   235  		return nil, nil, err
   236  	}
   237  
   238  	pubKey := elliptic.Marshal(curve, x, y)
   239  
   240  	done := func(theirPub []byte) ([]byte, error) {
   241  		// Verify and unpack node's public key.
   242  		x, y := elliptic.Unmarshal(curve, theirPub)
   243  		if x == nil {
   244  			return nil, fmt.Errorf("Malformed public key: %d %v", len(theirPub), theirPub)
   245  		}
   246  
   247  		if !curve.IsOnCurve(x, y) {
   248  			return nil, errors.New("Invalid public key.")
   249  		}
   250  
   251  		// Generate shared secret.
   252  		secret, _ := curve.ScalarMult(x, y, priv)
   253  
   254  		return secret.Bytes(), nil
   255  	}
   256  
   257  	return pubKey, done, nil
   258  }
   259  
   260  type StretchedKeys struct {
   261  	IV        []byte
   262  	MacKey    []byte
   263  	CipherKey []byte
   264  }
   265  
   266  func KeyStretcher(cipherType string, hashType string, secret []byte) (StretchedKeys, StretchedKeys) {
   267  	var cipherKeySize int
   268  	var ivSize int
   269  	switch cipherType {
   270  	case "AES-128":
   271  		ivSize = 16
   272  		cipherKeySize = 16
   273  	case "AES-256":
   274  		ivSize = 16
   275  		cipherKeySize = 32
   276  	case "Blowfish":
   277  		ivSize = 8
   278  		// Note: 24 arbitrarily selected, needs more thought
   279  		cipherKeySize = 32
   280  	}
   281  
   282  	hmacKeySize := 20
   283  
   284  	seed := []byte("key expansion")
   285  
   286  	result := make([]byte, 2*(ivSize+cipherKeySize+hmacKeySize))
   287  
   288  	var h func() hash.Hash
   289  
   290  	switch hashType {
   291  	case "SHA1":
   292  		h = sha1.New
   293  	case "SHA256":
   294  		h = sha256.New
   295  	case "SHA512":
   296  		h = sha512.New
   297  	default:
   298  		panic("Unrecognized hash function, programmer error?")
   299  	}
   300  
   301  	m := hmac.New(h, secret)
   302  	m.Write(seed)
   303  
   304  	a := m.Sum(nil)
   305  
   306  	j := 0
   307  	for j < len(result) {
   308  		m.Reset()
   309  		m.Write(a)
   310  		m.Write(seed)
   311  		b := m.Sum(nil)
   312  
   313  		todo := len(b)
   314  
   315  		if j+todo > len(result) {
   316  			todo = len(result) - j
   317  		}
   318  
   319  		copy(result[j:j+todo], b)
   320  
   321  		j += todo
   322  
   323  		m.Reset()
   324  		m.Write(a)
   325  		a = m.Sum(nil)
   326  	}
   327  
   328  	half := len(result) / 2
   329  	r1 := result[:half]
   330  	r2 := result[half:]
   331  
   332  	var k1 StretchedKeys
   333  	var k2 StretchedKeys
   334  
   335  	k1.IV = r1[0:ivSize]
   336  	k1.CipherKey = r1[ivSize : ivSize+cipherKeySize]
   337  	k1.MacKey = r1[ivSize+cipherKeySize:]
   338  
   339  	k2.IV = r2[0:ivSize]
   340  	k2.CipherKey = r2[ivSize : ivSize+cipherKeySize]
   341  	k2.MacKey = r2[ivSize+cipherKeySize:]
   342  
   343  	return k1, k2
   344  }
   345  
   346  func KeyEqual(a *ecdsa.PublicKey, b *ecdsa.PublicKey) bool {
   347  	abyte := CompressPubkey(a)
   348  	bbyte := CompressPubkey(b)
   349  
   350  	return bytes.Equal(abyte, bbyte)
   351  }
   352  
   353  //===== END ======
   354  
   355  func GenerateKey() (*ecdsa.PrivateKey, error) {
   356  	return ecdsa.GenerateKey(S256(), rand.Reader)
   357  }
   358  
   359  // ValidateSignatureValues verifies whether the signature values are valid with
   360  // the given chain rules. The v value is assumed to be either 0 or 1.
   361  func ValidateSignatureValues(v byte, r, s *big.Int, hubble bool) bool {
   362  	if r.Cmp(common.Big1) < 0 || s.Cmp(common.Big1) < 0 {
   363  		return false
   364  	}
   365  	// reject upper range of s values (ECDSA malleability)
   366  	// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
   367  	if hubble && s.Cmp(secp256k1halfN) > 0 {
   368  		return false
   369  	}
   370  	// Frontier: allow s to be in full N range
   371  	return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1)
   372  }
   373  
   374  func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
   375  	pubBytes := FromECDSAPub(&p)
   376  	return common.BytesToAddress(Keccak256(pubBytes[1:])[12:])
   377  }
   378  
   379  func zeroBytes(bytes []byte) {
   380  	for i := range bytes {
   381  		bytes[i] = 0
   382  	}
   383  }