github.com/annchain/OG@v0.0.9/ogcrypto/keccak.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package ogcrypto
    15  
    16  import (
    17  	"crypto/ecdsa"
    18  	"crypto/elliptic"
    19  	"crypto/rand"
    20  	"encoding/hex"
    21  	"errors"
    22  	"fmt"
    23  	"io"
    24  	"io/ioutil"
    25  	"math/big"
    26  	"os"
    27  
    28  	"github.com/annchain/commongo/math"
    29  	"github.com/btcsuite/btcd/btcec"
    30  	"golang.org/x/crypto/sha3"
    31  )
    32  
    33  var (
    34  	secp256k1N, _  = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
    35  	secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
    36  )
    37  
    38  var (
    39  	Big1   = big.NewInt(1)
    40  	Big2   = big.NewInt(2)
    41  	Big3   = big.NewInt(3)
    42  	Big0   = big.NewInt(0)
    43  	Big32  = big.NewInt(32)
    44  	Big256 = big.NewInt(256)
    45  	Big257 = big.NewInt(257)
    46  )
    47  
    48  var errInvalidPubkey = errors.New("invalid secp256k1 public key")
    49  
    50  // Keccak256 calculates and returns the Keccak256 hash of the input data.
    51  func Keccak256(data ...[]byte) []byte {
    52  	d := sha3.NewLegacyKeccak256()
    53  	for _, b := range data {
    54  		d.Write(b)
    55  	}
    56  	return d.Sum(nil)
    57  }
    58  
    59  // Keccak256Hash calculates and returns the Keccak256 hash of the input data,
    60  // converting it to an internal Hash data structure.
    61  func Keccak256Hash(data ...[]byte) []byte {
    62  	d := sha3.NewLegacyKeccak256()
    63  	for _, b := range data {
    64  		d.Write(b)
    65  	}
    66  
    67  	return d.Sum([]byte{})
    68  }
    69  
    70  // Keccak512 calculates and returns the Keccak512 hash of the input data.
    71  func Keccak512(data ...[]byte) []byte {
    72  	d := sha3.NewLegacyKeccak512()
    73  	for _, b := range data {
    74  		d.Write(b)
    75  	}
    76  	return d.Sum(nil)
    77  }
    78  
    79  // ToECDSA creates a private key with the given D value.
    80  func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
    81  	return toECDSA(d, true)
    82  }
    83  
    84  // ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost
    85  // never be used unless you are sure the input is valid and want to avoid hitting
    86  // errors due to bad origin encoding (0 prefixes cut off).
    87  func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey {
    88  	priv, _ := toECDSA(d, false)
    89  	return priv
    90  }
    91  
    92  // toECDSA creates a private key with the given D value. The strict parameter
    93  // controls whether the key's length should be enforced at the curve size or
    94  // it can also accept legacy encodings (0 prefixes).
    95  func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
    96  	priv := new(ecdsa.PrivateKey)
    97  	priv.PublicKey.Curve = S256()
    98  	if strict && 8*len(d) != priv.Params().BitSize {
    99  		return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
   100  	}
   101  	priv.D = new(big.Int).SetBytes(d)
   102  
   103  	// The priv.D must < N
   104  	if priv.D.Cmp(secp256k1N) >= 0 {
   105  		return nil, fmt.Errorf("invalid private key, >=N")
   106  	}
   107  	// The priv.D must not be zero or negative.
   108  	if priv.D.Sign() <= 0 {
   109  		return nil, fmt.Errorf("invalid private key, zero or negative")
   110  	}
   111  
   112  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
   113  	if priv.PublicKey.X == nil {
   114  		return nil, errors.New("invalid private key")
   115  	}
   116  	return priv, nil
   117  }
   118  
   119  // FromECDSA exports a private key into a binary dump.
   120  func FromECDSA(priv *ecdsa.PrivateKey) []byte {
   121  	if priv == nil {
   122  		return nil
   123  	}
   124  	return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
   125  }
   126  
   127  // UnmarshalPubkey converts bytes to a secp256k1 public key.
   128  func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
   129  	x, y := elliptic.Unmarshal(S256(), pub)
   130  	if x == nil {
   131  		return nil, errInvalidPubkey
   132  	}
   133  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
   134  }
   135  
   136  func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
   137  	if pub == nil || pub.X == nil || pub.Y == nil {
   138  		return nil
   139  	}
   140  	return elliptic.Marshal(S256(), pub.X, pub.Y)
   141  }
   142  
   143  // HexToECDSA parses a secp256k1 private key.
   144  func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
   145  	b, err := hex.DecodeString(hexkey)
   146  	if err != nil {
   147  		return nil, errors.New("invalid hex string")
   148  	}
   149  	return ToECDSA(b)
   150  }
   151  
   152  // LoadECDSA loads a secp256k1 private key from the given file.
   153  func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
   154  	buf := make([]byte, 64)
   155  	fd, err := os.Open(file)
   156  	if err != nil {
   157  		return nil, err
   158  	}
   159  	defer fd.Close()
   160  	if _, err := io.ReadFull(fd, buf); err != nil {
   161  		return nil, err
   162  	}
   163  
   164  	key, err := hex.DecodeString(string(buf))
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	return ToECDSA(key)
   169  }
   170  
   171  // SaveECDSA saves a secp256k1 private key to the given file with
   172  // restrictive permissions. The key data is saved hex-encoded.
   173  func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
   174  	data := FromECDSA(key)
   175  	k := hex.EncodeToString(data)
   176  	return ioutil.WriteFile(file, []byte(k), 0600)
   177  }
   178  
   179  func GenerateKey() (*ecdsa.PrivateKey, error) {
   180  	return ecdsa.GenerateKey(S256(), rand.Reader)
   181  }
   182  
   183  // ValidateSignatureValues verifies whether the signature values are valid with
   184  // the given chain rules. The v value is assumed to be either 0 or 1.
   185  func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool {
   186  	if r.Cmp(Big1) < 0 || s.Cmp(Big1) < 0 {
   187  		return false
   188  	}
   189  	// reject upper range of s values (ECDSA malleability)
   190  	// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
   191  	if homestead && s.Cmp(secp256k1halfN) > 0 {
   192  		return false
   193  	}
   194  	// Frontier: allow s to be in full N range
   195  	return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1)
   196  }
   197  
   198  //func PubkeyToAddress(p ecdsa.PublicKey) og_types.Address {
   199  //	pubBytes := FromECDSAPub(&p)
   200  //	addr, _ := og_types.BytesToAddress20(Keccak256(pubBytes[1:])[12:])
   201  //	return addr
   202  //}
   203  
   204  func zeroBytes(bytes []byte) {
   205  	for i := range bytes {
   206  		bytes[i] = 0
   207  	}
   208  }
   209  
   210  // Sign calculates an ECDSA signature.
   211  //
   212  // This function is susceptible to chosen plaintext attacks that can leak
   213  // information about the private key that is used for signing. Callers must
   214  // be aware that the given hash cannot be chosen by an adversery. Common
   215  // solution is to hash any input before calculating the signature.
   216  //
   217  // The produced signature is in the [R || S || V] format where V is 0 or 1.
   218  func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) {
   219  	if len(hash) != 32 {
   220  		return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash))
   221  	}
   222  	if prv.Curve != btcec.S256() {
   223  		return nil, fmt.Errorf("private key curve is not secp256k1")
   224  	}
   225  	sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false)
   226  	if err != nil {
   227  		return nil, err
   228  	}
   229  	// Convert to Ethereum signature format with 'recovery id' v at the end.
   230  	v := sig[0] - 27
   231  	copy(sig, sig[1:])
   232  	sig[64] = v
   233  	return sig, nil
   234  }
   235  
   236  // VerifySignature checks that the given public key created signature over hash.
   237  // The public key should be in compressed (33 bytes) or uncompressed (65 bytes) format.
   238  // The signature should have the 64 byte [R || S] format.
   239  func VerifySignature(pubkey, hash, signature []byte) bool {
   240  	if len(signature) != 64 {
   241  		return false
   242  	}
   243  	sig := &btcec.Signature{R: new(big.Int).SetBytes(signature[:32]), S: new(big.Int).SetBytes(signature[32:])}
   244  	key, err := btcec.ParsePubKey(pubkey, btcec.S256())
   245  	if err != nil {
   246  		return false
   247  	}
   248  	// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
   249  	if sig.S.Cmp(secp256k1halfN) > 0 {
   250  		return false
   251  	}
   252  	return sig.Verify(hash, key)
   253  }
   254  
   255  // DecompressPubkey parses a public key in the 33-byte compressed format.
   256  func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) {
   257  	if len(pubkey) != 33 {
   258  		return nil, errors.New("invalid compressed public key length")
   259  	}
   260  	key, err := btcec.ParsePubKey(pubkey, btcec.S256())
   261  	if err != nil {
   262  		return nil, err
   263  	}
   264  	return key.ToECDSA(), nil
   265  }
   266  
   267  // CompressPubkey encodes a public key to the 33-byte compressed format.
   268  func CompressPubkey(pubkey *ecdsa.PublicKey) []byte {
   269  	return (*btcec.PublicKey)(pubkey).SerializeCompressed()
   270  }
   271  
   272  // S256 returns an instance of the secp256k1 curve.
   273  func S256() elliptic.Curve {
   274  	return btcec.S256()
   275  }