github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/go/src/sawtooth_sdk/signing/secp256k1.go (about) 1 /** 2 * Copyright 2017 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * ------------------------------------------------------------------------------ 16 */ 17 18 package signing 19 20 import ( 21 "crypto/sha256" 22 "crypto/sha512" 23 "encoding/hex" 24 ellcurv "github.com/btcsuite/btcd/btcec" 25 "math/big" 26 ) 27 28 var cachedCurve = ellcurv.S256() 29 30 // -- Private Key -- 31 32 type Secp256k1PrivateKey struct { 33 private_key []byte 34 } 35 36 // Creates a PrivateKey instance from private key bytes. 37 func NewSecp256k1PrivateKey(private_key []byte) PrivateKey { 38 return &Secp256k1PrivateKey{private_key} 39 } 40 41 // PemToSecp256k1PrivateKey converts a PEM string to a private key. 42 func PemToSecp256k1PrivateKey(pem string, password string) (*Secp256k1PrivateKey, error) { 43 priv, err := pemToPriv(pem, password) 44 if err != nil { 45 return nil, err 46 } 47 48 return &Secp256k1PrivateKey{priv}, nil 49 } 50 51 // Returns the string "secp256k1". 52 func (self *Secp256k1PrivateKey) GetAlgorithmName() string { 53 return "secp256k1" 54 } 55 56 // Returns the private key as a hex-encoded string. 57 func (self *Secp256k1PrivateKey) AsHex() string { 58 return hex.EncodeToString(self.private_key) 59 } 60 61 // Returns the bytes of the private key. 62 func (self *Secp256k1PrivateKey) AsBytes() []byte { 63 return self.private_key 64 } 65 66 // -- Public Key -- 67 68 type Secp256k1PublicKey struct { 69 public_key []byte 70 } 71 72 // Creates a PublicKey instance from public key bytes. 73 func NewSecp256k1PublicKey(public_key []byte) PublicKey { 74 return &Secp256k1PublicKey{public_key} 75 } 76 77 // Returns the string "secp256k1". 78 func (self *Secp256k1PublicKey) GetAlgorithmName() string { 79 return "secp256k1" 80 } 81 82 // Returns the public key as a hex-encoded string. 83 func (self *Secp256k1PublicKey) AsHex() string { 84 return hex.EncodeToString(self.public_key) 85 } 86 87 // Returns the bytes of the public key. 88 func (self *Secp256k1PublicKey) AsBytes() []byte { 89 return self.public_key 90 } 91 92 // -- Context -- 93 94 type Secp256k1Context struct { 95 curve *ellcurv.KoblitzCurve 96 } 97 98 // Returns a new secp256k1 context. 99 func NewSecp256k1Context() Context { 100 return &Secp256k1Context{ellcurv.S256()} 101 } 102 103 // Returns the string "secp256k1". 104 func (self *Secp256k1Context) GetAlgorithmName() string { 105 return "secp256k1" 106 } 107 108 // Generates a new random secp256k1 private key. 109 func (self *Secp256k1Context) NewRandomPrivateKey() PrivateKey { 110 priv, _ := ellcurv.NewPrivateKey(cachedCurve) 111 112 return &Secp256k1PrivateKey{priv.Serialize()} 113 } 114 115 // Produces a public key for the given private key. 116 func (self *Secp256k1Context) GetPublicKey(private_key PrivateKey) PublicKey { 117 _, public_key := ellcurv.PrivKeyFromBytes( 118 cachedCurve, 119 private_key.AsBytes()) 120 121 return NewSecp256k1PublicKey(public_key.SerializeCompressed()) 122 } 123 124 // Sign uses the given private key to calculate a signature for the 125 // given data. A sha256 hash of the data is first calculated and this 126 // is what is actually signed. Returns the signature as bytes using 127 // the compact serialization (which is just (r, s)). 128 func (self *Secp256k1Context) Sign(message []byte, private_key PrivateKey) []byte { 129 priv, _ := ellcurv.PrivKeyFromBytes( 130 self.curve, 131 private_key.AsBytes()) 132 133 hash := doSHA256(message) 134 135 sig, err := priv.Sign(hash) 136 if err != nil { 137 panic("Signing failed") 138 } 139 140 return serializeCompact(sig) 141 } 142 143 // Verify uses the given public key to verify that the given signature 144 // was created from the given data using the associated private key. A 145 // sha256 hash of the data is calculated first and this is what is 146 // actually used to verify the signature. 147 func (self *Secp256k1Context) Verify(signature []byte, message []byte, public_key PublicKey) bool { 148 sig := deserializeCompact(signature) 149 hash := doSHA256(message) 150 151 pub, err := ellcurv.ParsePubKey( 152 public_key.AsBytes(), 153 self.curve) 154 if err != nil { 155 panic(err.Error()) 156 } 157 158 return sig.Verify(hash, pub) 159 } 160 161 // -- SHA -- 162 163 func doSHA512(input []byte) []byte { 164 hash := sha512.New() 165 hash.Write(input) 166 return hash.Sum(nil) 167 } 168 169 func doSHA256(input []byte) []byte { 170 hash := sha256.New() 171 hash.Write(input) 172 return hash.Sum(nil) 173 } 174 175 func pemToPriv(pem string, password string) ([]byte, error) { 176 pemlen := len(pem) 177 priv, _, err := loadPemKey(pem, pemlen, password) 178 if err != nil { 179 return nil, err 180 } 181 return hex.DecodeString(priv) 182 } 183 184 // --- 185 186 func serializeCompact(sig *ellcurv.Signature) []byte { 187 b := make([]byte, 0, 64) 188 // TODO: Padding 189 rbytes := pad(sig.R.Bytes(), 32) 190 sbytes := pad(sig.S.Bytes(), 32) 191 b = append(b, rbytes...) 192 b = append(b, sbytes...) 193 if len(b) != 64 { 194 panic("Invalid signature length") 195 } 196 return b 197 } 198 199 func deserializeCompact(b []byte) *ellcurv.Signature { 200 return &ellcurv.Signature{ 201 R: new(big.Int).SetBytes(b[:32]), 202 S: new(big.Int).SetBytes(b[32:]), 203 } 204 } 205 206 func pad(buf []byte, size int) []byte { 207 newbuf := make([]byte, 0, size) 208 padLength := size - len(buf) 209 for i := 0; i < padLength; i++ { 210 newbuf = append(newbuf, 0) 211 } 212 return append(newbuf, buf...) 213 }