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