github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/crypto/ecdsa.go (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  // use btcec https://godoc.org/github.com/btcsuite/btcd/btcec#example-package--VerifySignature
    20  
    21  package crypto
    22  
    23  import (
    24  	"crypto/ecdsa"
    25  	"crypto/elliptic"
    26  	"crypto/rand"
    27  	"encoding/hex"
    28  	"errors"
    29  	"fmt"
    30  	"io"
    31  	"math/big"
    32  
    33  	"github.com/sixexorg/magnetic-ring/crypto/secp256k1/bitelliptic"
    34  )
    35  
    36  const (
    37  	// number of bits in a big.Word
    38  	wordBits = 32 << (uint64(^big.Word(0)) >> 63)
    39  	// number of bytes in a big.Word
    40  	wordBytes = wordBits / 8
    41  )
    42  
    43  // S256 returns an instance of the secp256k1 curve.
    44  func S256() elliptic.Curve {
    45  	return bitelliptic.S256()
    46  }
    47  
    48  // GenerateKey
    49  func generateEcdsaKey() (*ecdsa.PrivateKey, error) {
    50  	return ecdsa.GenerateKey(S256(), rand.Reader)
    51  }
    52  
    53  // Sign
    54  func Sign(pk *ecdsa.PrivateKey, hash []byte) ([]byte, error) {
    55  	r, s, err := ecdsa.Sign(rand.Reader, pk, hash)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	return serializeSignature(r, s), nil
    61  }
    62  
    63  // Verify
    64  func Verify(pub *ecdsa.PublicKey, hash, sig []byte) (bool, error) {
    65  	r, s, err := deserializeSignature(sig)
    66  	if err != nil {
    67  		return false, err
    68  	}
    69  	return ecdsa.Verify(pub, hash, r, s), nil
    70  }
    71  
    72  // HexToECDSAPrivateKey parses a secp256k1 private key.
    73  func HexToECDSAPrivateKey(hexkey string) (*ecdsa.PrivateKey, error) {
    74  	b, err := hex.DecodeString(hexkey)
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  	return ToECDSAPrivateKey(b)
    79  }
    80  
    81  // ToECDSAPrivateKey creates a private key with the given data value.
    82  func ToECDSAPrivateKey(d []byte) (*ecdsa.PrivateKey, error) {
    83  	priv := new(ecdsa.PrivateKey)
    84  	priv.PublicKey.Curve = S256()
    85  	priv.D = new(big.Int).SetBytes(d)
    86  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
    87  	return priv, nil
    88  }
    89  
    90  // ToECDSAPublicKey creates a public key with the given data value.
    91  func ToECDSAPublicKey(pub []byte) (*ecdsa.PublicKey, error) {
    92  	if len(pub) == 0 {
    93  		return nil, errors.New("ecdsa: please input public key bytes")
    94  	}
    95  	x, y := elliptic.Unmarshal(S256(), pub)
    96  	return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
    97  }
    98  
    99  // paddedBigBytes encodes a big integer as a big-endian byte slice.
   100  func paddedBigBytes(bigint *big.Int, n int) []byte {
   101  	if bigint.BitLen()/8 >= n {
   102  		return bigint.Bytes()
   103  	}
   104  	ret := make([]byte, n)
   105  	readBits(bigint, ret)
   106  	return ret
   107  }
   108  
   109  // readBits encodes the absolute value of bigint as big-endian bytes.
   110  func readBits(bigint *big.Int, buf []byte) {
   111  	i := len(buf)
   112  	for _, d := range bigint.Bits() {
   113  		for j := 0; j < wordBytes && i > 0; j++ {
   114  			i--
   115  			buf[i] = byte(d)
   116  			d >>= 8
   117  		}
   118  	}
   119  }
   120  
   121  func serializeSignature(r, s *big.Int) []byte {
   122  	size := (params.BitSize + 7) >> 3
   123  	res := make([]byte, size*2)
   124  
   125  	rBytes := r.Bytes()
   126  	sBytes := s.Bytes()
   127  	copy(res[size-len(rBytes):], rBytes)
   128  	copy(res[size*2-len(sBytes):], sBytes)
   129  	return res
   130  }
   131  
   132  func deserializeSignature(buf []byte) (r, s *big.Int, err error) {
   133  	if buf == nil {
   134  		panic("deserializeSignature: invalid argument")
   135  	}
   136  
   137  	length := len(buf)
   138  	if length&1 != 0 {
   139  		return nil, nil, errors.New("invalid length")
   140  	}
   141  
   142  	r = new(big.Int).SetBytes(buf[0 : length/2])
   143  	s = new(big.Int).SetBytes(buf[length/2:])
   144  	return r, s, nil
   145  }
   146  
   147  // ZeroKey zeroes the private key
   148  func ZeroKey(k *ecdsa.PrivateKey) {
   149  	b := k.D.Bits()
   150  	for i := range b {
   151  		b[i] = 0
   152  	}
   153  }
   154  
   155  var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
   156  
   157  func generateKeyFromCurve(curve *bitelliptic.BitCurve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
   158  	N := curve.Params().N
   159  	bitSize := N.BitLen()
   160  	byteLen := (bitSize + 7) >> 3
   161  	priv = make([]byte, byteLen)
   162  
   163  	for x == nil {
   164  		_, err = io.ReadFull(rand, priv)
   165  		if err != nil {
   166  			return
   167  		}
   168  
   169  		// We have to mask off any excess bits in the case that the size of the
   170  		// underlying field is not a whole number of bytes.
   171  		priv[0] &= mask[bitSize%8]
   172  		// This is because, in tests, rand will return all zeros and we don't
   173  		// want to get the point at infinity and loop forever.
   174  		priv[1] ^= 0x42
   175  
   176  		// If the scalar is out of range, sample another random number.
   177  		if new(big.Int).SetBytes(priv).Cmp(N) >= 0 {
   178  			continue
   179  		}
   180  
   181  		x, y = curve.ScalarBaseMult(priv)
   182  	}
   183  	return
   184  }
   185  
   186  func toECDSA(d []byte) (*ecdsa.PrivateKey, error) {
   187  	priv := new(ecdsa.PrivateKey)
   188  	priv.PublicKey.Curve = curve
   189  	if 8*len(d) != priv.Params().BitSize {
   190  		return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
   191  	}
   192  	priv.D = new(big.Int).SetBytes(d)
   193  
   194  	// The priv.D must < N
   195  	if priv.D.Cmp(curve.N) >= 0 {
   196  		return nil, fmt.Errorf("invalid private key, >=N")
   197  	}
   198  	// The priv.D must not be zero or negative.
   199  	if priv.D.Sign() <= 0 {
   200  		return nil, fmt.Errorf("invalid private key, zero or negative")
   201  	}
   202  
   203  	priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
   204  	if priv.PublicKey.X == nil {
   205  		return nil, errors.New("invalid private key")
   206  	}
   207  
   208  	return priv, nil
   209  }