github.com/consensys/gnark-crypto@v0.14.0/ecc/secp256k1/ecdsa/ecdsa.go (about) 1 // Copyright 2020 Consensys Software Inc. 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 15 // Code generated by consensys/gnark-crypto DO NOT EDIT 16 17 package ecdsa 18 19 import ( 20 "crypto/aes" 21 "crypto/cipher" 22 "crypto/rand" 23 "crypto/sha512" 24 "crypto/subtle" 25 "errors" 26 "hash" 27 "io" 28 "math/big" 29 30 "github.com/consensys/gnark-crypto/ecc/secp256k1" 31 "github.com/consensys/gnark-crypto/ecc/secp256k1/fp" 32 "github.com/consensys/gnark-crypto/ecc/secp256k1/fr" 33 "github.com/consensys/gnark-crypto/signature" 34 ) 35 36 const ( 37 sizeFr = fr.Bytes 38 sizeFrBits = fr.Bits 39 sizeFp = fp.Bytes 40 sizePublicKey = 2 * sizeFp 41 sizePrivateKey = sizeFr + sizePublicKey 42 sizeSignature = 2 * sizeFr 43 ) 44 45 var ( 46 // ErrNoSqrtR is returned when x^3+ax+b is not a square in the field. This 47 // is used for public key recovery and allows to detect if the signature is 48 // valid or not. 49 ErrNoSqrtR = errors.New("x^3+ax+b is not a square in the field") 50 ) 51 52 var order = fr.Modulus() 53 54 // PublicKey represents an ECDSA public key 55 type PublicKey struct { 56 A secp256k1.G1Affine 57 } 58 59 // PrivateKey represents an ECDSA private key 60 type PrivateKey struct { 61 PublicKey PublicKey 62 scalar [sizeFr]byte // secret scalar, in big Endian 63 } 64 65 // Signature represents an ECDSA signature 66 type Signature struct { 67 R, S [sizeFr]byte 68 } 69 70 var one = new(big.Int).SetInt64(1) 71 72 // randFieldElement returns a random element of the order of the given 73 // curve using the procedure given in FIPS 186-4, Appendix B.5.1. 74 func randFieldElement(rand io.Reader) (k *big.Int, err error) { 75 b := make([]byte, fr.Bits/8+8) 76 _, err = io.ReadFull(rand, b) 77 if err != nil { 78 return 79 } 80 81 k = new(big.Int).SetBytes(b) 82 n := new(big.Int).Sub(order, one) 83 k.Mod(k, n) 84 k.Add(k, one) 85 return 86 } 87 88 // GenerateKey generates a public and private key pair. 89 func GenerateKey(rand io.Reader) (*PrivateKey, error) { 90 91 k, err := randFieldElement(rand) 92 if err != nil { 93 return nil, err 94 95 } 96 _, g := secp256k1.Generators() 97 98 privateKey := new(PrivateKey) 99 k.FillBytes(privateKey.scalar[:sizeFr]) 100 privateKey.PublicKey.A.ScalarMultiplication(&g, k) 101 return privateKey, nil 102 } 103 104 // HashToInt converts a hash value to an integer. Per FIPS 186-4, Section 6.4, 105 // we use the left-most bits of the hash to match the bit-length of the order of 106 // the curve. This also performs Step 5 of SEC 1, Version 2.0, Section 4.1.3. 107 func HashToInt(hash []byte) *big.Int { 108 if len(hash) > sizeFr { 109 hash = hash[:sizeFr] 110 } 111 ret := new(big.Int).SetBytes(hash) 112 excess := ret.BitLen() - sizeFrBits 113 if excess > 0 { 114 ret.Rsh(ret, uint(excess)) 115 } 116 return ret 117 } 118 119 // recoverP recovers the value P (prover commitment) when creating a signature. 120 // It uses the recovery information v and part of the decomposed signature r. It 121 // is used internally for recovering the public key. 122 func recoverP(v uint, r *big.Int) (*secp256k1.G1Affine, error) { 123 if r.Cmp(fr.Modulus()) >= 0 { 124 return nil, errors.New("r is larger than modulus") 125 } 126 if r.Cmp(big.NewInt(0)) <= 0 { 127 return nil, errors.New("r is negative") 128 } 129 x := new(big.Int).Set(r) 130 // if x is r or r+N 131 xChoice := (v & 2) >> 1 132 // if y is y or -y 133 yChoice := v & 1 134 // decompose limbs into big.Int value 135 // conditional +n based on xChoice 136 kn := big.NewInt(int64(xChoice)) 137 kn.Mul(kn, fr.Modulus()) 138 x.Add(x, kn) 139 // y^2 = x^3+ax+b 140 a, b := secp256k1.CurveCoefficients() 141 y := new(big.Int).Exp(x, big.NewInt(3), fp.Modulus()) 142 if !a.IsZero() { 143 y.Add(y, new(big.Int).Mul(a.BigInt(new(big.Int)), x)) 144 } 145 y.Add(y, b.BigInt(new(big.Int))) 146 y.Mod(y, fp.Modulus()) 147 // y = sqrt(y^2) 148 if y.ModSqrt(y, fp.Modulus()) == nil { 149 // there is no square root, return error constant 150 return nil, ErrNoSqrtR 151 } 152 // check that y has same oddity as defined by v 153 if y.Bit(0) != yChoice { 154 y = y.Sub(fp.Modulus(), y) 155 } 156 return &secp256k1.G1Affine{ 157 X: *new(fp.Element).SetBigInt(x), 158 Y: *new(fp.Element).SetBigInt(y), 159 }, nil 160 } 161 162 type zr struct{} 163 164 // Read replaces the contents of dst with zeros. It is safe for concurrent use. 165 func (zr) Read(dst []byte) (n int, err error) { 166 for i := range dst { 167 dst[i] = 0 168 } 169 return len(dst), nil 170 } 171 172 var zeroReader = zr{} 173 174 const ( 175 aesIV = "gnark-crypto IV." // must be 16 chars (equal block size) 176 ) 177 178 func nonce(privateKey *PrivateKey, hash []byte) (csprng *cipher.StreamReader, err error) { 179 // This implementation derives the nonce from an AES-CTR CSPRNG keyed by: 180 // 181 // SHA2-512(privateKey.scalar ∥ entropy ∥ hash)[:32] 182 // 183 // The CSPRNG key is indifferentiable from a random oracle as shown in 184 // [Coron], the AES-CTR stream is indifferentiable from a random oracle 185 // under standard cryptographic assumptions (see [Larsson] for examples). 186 // 187 // [Coron]: https://cs.nyu.edu/~dodis/ps/merkle.pdf 188 // [Larsson]: https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf 189 190 // Get 256 bits of entropy from rand. 191 entropy := make([]byte, 32) 192 _, err = io.ReadFull(rand.Reader, entropy) 193 if err != nil { 194 return 195 196 } 197 198 // Initialize an SHA-512 hash context; digest... 199 md := sha512.New() 200 md.Write(privateKey.scalar[:sizeFr]) // the private key, 201 md.Write(entropy) // the entropy, 202 md.Write(hash) // and the input hash; 203 key := md.Sum(nil)[:32] // and compute ChopMD-256(SHA-512), 204 // which is an indifferentiable MAC. 205 206 // Create an AES-CTR instance to use as a CSPRNG. 207 block, _ := aes.NewCipher(key) 208 209 // Create a CSPRNG that xors a stream of zeros with 210 // the output of the AES-CTR instance. 211 csprng = &cipher.StreamReader{ 212 R: zeroReader, 213 S: cipher.NewCTR(block, []byte(aesIV)), 214 } 215 216 return csprng, err 217 } 218 219 // Equal compares 2 public keys 220 func (pub *PublicKey) Equal(x signature.PublicKey) bool { 221 xx, ok := x.(*PublicKey) 222 if !ok { 223 return false 224 } 225 bpk := pub.Bytes() 226 bxx := xx.Bytes() 227 return subtle.ConstantTimeCompare(bpk, bxx) == 1 228 } 229 230 // Public returns the public key associated to the private key. 231 func (privKey *PrivateKey) Public() signature.PublicKey { 232 var pub PublicKey 233 pub.A.Set(&privKey.PublicKey.A) 234 return &pub 235 } 236 237 // SignForRecover performs the ECDSA signature and returns public key recovery information 238 // 239 // k ← 𝔽r (random) 240 // P = k ⋅ g1Gen 241 // r = x_P (mod order) 242 // s = k⁻¹ . (m + sk ⋅ r) 243 // v = (div(x_P, order)<<1) || y_P[-1] 244 // 245 // SEC 1, Version 2.0, Section 4.1.3 246 func (privKey *PrivateKey) SignForRecover(message []byte, hFunc hash.Hash) (v uint, r, s *big.Int, err error) { 247 r, s = new(big.Int), new(big.Int) 248 249 scalar, kInv := new(big.Int), new(big.Int) 250 scalar.SetBytes(privKey.scalar[:sizeFr]) 251 for { 252 for { 253 csprng, err := nonce(privKey, message) 254 if err != nil { 255 return 0, nil, nil, err 256 } 257 k, err := randFieldElement(csprng) 258 if err != nil { 259 return 0, nil, nil, err 260 } 261 262 var P secp256k1.G1Affine 263 P.ScalarMultiplicationBase(k) 264 kInv.ModInverse(k, order) 265 266 P.X.BigInt(r) 267 // set how many times we overflow the scalar field 268 v |= (uint(new(big.Int).Div(r, order).Uint64())) << 1 269 // set if y is even or odd 270 v |= P.Y.BigInt(new(big.Int)).Bit(0) 271 272 r.Mod(r, order) 273 if r.Sign() != 0 { 274 break 275 } 276 } 277 s.Mul(r, scalar) 278 279 var m *big.Int 280 if hFunc != nil { 281 // compute the hash of the message as an integer 282 dataToHash := make([]byte, len(message)) 283 copy(dataToHash[:], message[:]) 284 hFunc.Reset() 285 _, err := hFunc.Write(dataToHash[:]) 286 if err != nil { 287 return 0, nil, nil, err 288 } 289 hramBin := hFunc.Sum(nil) 290 m = HashToInt(hramBin) 291 } else { 292 m = HashToInt(message) 293 } 294 295 s.Add(m, s). 296 Mul(kInv, s). 297 Mod(s, order) // order != 0 298 if s.Sign() != 0 { 299 break 300 } 301 } 302 303 return v, r, s, nil 304 } 305 306 // Sign performs the ECDSA signature 307 // 308 // k ← 𝔽r (random) 309 // P = k ⋅ g1Gen 310 // r = x_P (mod order) 311 // s = k⁻¹ . (m + sk ⋅ r) 312 // signature = {r, s} 313 // 314 // SEC 1, Version 2.0, Section 4.1.3 315 func (privKey *PrivateKey) Sign(message []byte, hFunc hash.Hash) ([]byte, error) { 316 _, r, s, err := privKey.SignForRecover(message, hFunc) 317 if err != nil { 318 return nil, err 319 } 320 var sig Signature 321 r.FillBytes(sig.R[:sizeFr]) 322 s.FillBytes(sig.S[:sizeFr]) 323 324 return sig.Bytes(), nil 325 } 326 327 // Verify validates the ECDSA signature 328 // 329 // R ?= (s⁻¹ ⋅ m ⋅ Base + s⁻¹ ⋅ R ⋅ publiKey)_x 330 // 331 // SEC 1, Version 2.0, Section 4.1.4 332 func (publicKey *PublicKey) Verify(sigBin, message []byte, hFunc hash.Hash) (bool, error) { 333 334 // Deserialize the signature 335 var sig Signature 336 if _, err := sig.SetBytes(sigBin); err != nil { 337 return false, err 338 } 339 340 r, s := new(big.Int), new(big.Int) 341 r.SetBytes(sig.R[:sizeFr]) 342 s.SetBytes(sig.S[:sizeFr]) 343 344 sInv := new(big.Int).ModInverse(s, order) 345 346 var m *big.Int 347 if hFunc != nil { 348 // compute the hash of the message as an integer 349 dataToHash := make([]byte, len(message)) 350 copy(dataToHash[:], message[:]) 351 hFunc.Reset() 352 _, err := hFunc.Write(dataToHash[:]) 353 if err != nil { 354 return false, err 355 } 356 hramBin := hFunc.Sum(nil) 357 m = HashToInt(hramBin) 358 } else { 359 m = HashToInt(message) 360 } 361 362 u1 := new(big.Int).Mul(m, sInv) 363 u1.Mod(u1, order) 364 u2 := new(big.Int).Mul(r, sInv) 365 u2.Mod(u2, order) 366 var U secp256k1.G1Jac 367 U.JointScalarMultiplicationBase(&publicKey.A, u1, u2) 368 369 var z big.Int 370 U.Z.Square(&U.Z). 371 Inverse(&U.Z). 372 Mul(&U.Z, &U.X). 373 BigInt(&z) 374 375 z.Mod(&z, order) 376 377 return z.Cmp(r) == 0, nil 378 379 }