github.com/igggame/nebulas-go@v2.1.0+incompatible/crypto/keystore/secp256k1/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 secp256k1 22 23 import ( 24 "crypto/ecdsa" 25 "crypto/elliptic" 26 27 "encoding/hex" 28 "errors" 29 "math/big" 30 31 "crypto/rand" 32 33 "github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1/bitelliptic" 34 ) 35 36 // S256 returns an instance of the secp256k1 curve. 37 func S256() elliptic.Curve { 38 return bitelliptic.S256() 39 } 40 41 // NewECDSAPrivateKey generate a ecdsa private key 42 func NewECDSAPrivateKey() (*ecdsa.PrivateKey, error) { 43 var priv *ecdsa.PrivateKey 44 45 // in bitcoin src, they call SeckeyVerify func to verify the generated private key 46 // to make sure valid. 47 for { 48 privKey, err := ecdsa.GenerateKey(S256(), rand.Reader) 49 if err != nil { 50 return nil, err 51 } 52 privData, err := FromECDSAPrivateKey(privKey) 53 if err != nil { 54 return nil, err 55 } 56 priv = privKey 57 if SeckeyVerify(privData) { 58 break 59 } 60 } 61 return priv, nil 62 } 63 64 // FromECDSAPrivateKey exports a private key into a binary dump. 65 func FromECDSAPrivateKey(priv *ecdsa.PrivateKey) ([]byte, error) { 66 if priv == nil { 67 return nil, errors.New("ecdsa: please input private key") 68 } 69 // as private key len cannot guarantee greater than Params bytes len, padding big bytes. 70 return paddedBigBytes(priv.D, priv.Params().BitSize/8), nil 71 } 72 73 // FromECDSAPublicKey exports a public key into a binary dump. 74 func FromECDSAPublicKey(pub *ecdsa.PublicKey) ([]byte, error) { 75 if pub == nil || pub.X == nil || pub.Y == nil { 76 return nil, errors.New("ecdsa: please input public key") 77 } 78 return elliptic.Marshal(S256(), pub.X, pub.Y), nil 79 } 80 81 // HexToECDSAPrivateKey parses a secp256k1 private key. 82 func HexToECDSAPrivateKey(hexkey string) (*ecdsa.PrivateKey, error) { 83 b, err := hex.DecodeString(hexkey) 84 if err != nil { 85 return nil, err 86 } 87 return ToECDSAPrivateKey(b) 88 } 89 90 // ToECDSAPrivateKey creates a private key with the given data value. 91 func ToECDSAPrivateKey(d []byte) (*ecdsa.PrivateKey, error) { 92 priv := new(ecdsa.PrivateKey) 93 priv.PublicKey.Curve = S256() 94 priv.D = new(big.Int).SetBytes(d) 95 priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d) 96 return priv, nil 97 } 98 99 // ToECDSAPublicKey creates a public key with the given data value. 100 func ToECDSAPublicKey(pub []byte) (*ecdsa.PublicKey, error) { 101 if len(pub) == 0 { 102 return nil, errors.New("ecdsa: please input public key bytes") 103 } 104 x, y := elliptic.Unmarshal(S256(), pub) 105 return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil 106 } 107 108 // zeroKey zeroes the private key 109 func zeroKey(k *ecdsa.PrivateKey) { 110 b := k.D.Bits() 111 for i := range b { 112 b[i] = 0 113 } 114 } 115 116 // paddedBigBytes encodes a big integer as a big-endian byte slice. 117 func paddedBigBytes(bigint *big.Int, n int) []byte { 118 if bigint.BitLen()/8 >= n { 119 return bigint.Bytes() 120 } 121 ret := make([]byte, n) 122 readBits(bigint, ret) 123 return ret 124 } 125 126 const ( 127 // number of bits in a big.Word 128 wordBits = 32 << (uint64(^big.Word(0)) >> 63) 129 // number of bytes in a big.Word 130 wordBytes = wordBits / 8 131 ) 132 133 // readBits encodes the absolute value of bigint as big-endian bytes. 134 func readBits(bigint *big.Int, buf []byte) { 135 i := len(buf) 136 for _, d := range bigint.Bits() { 137 for j := 0; j < wordBytes && i > 0; j++ { 138 i-- 139 buf[i] = byte(d) 140 d >>= 8 141 } 142 } 143 }