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 }