github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/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 "hash" 26 "io" 27 "math/big" 28 29 "github.com/consensys/gnark-crypto/ecc/bls12-378" 30 "github.com/consensys/gnark-crypto/ecc/bls12-378/fp" 31 "github.com/consensys/gnark-crypto/ecc/bls12-378/fr" 32 "github.com/consensys/gnark-crypto/signature" 33 ) 34 35 const ( 36 sizeFr = fr.Bytes 37 sizeFrBits = fr.Bits 38 sizeFp = fp.Bytes 39 sizePublicKey = sizeFp 40 sizePrivateKey = sizeFr + sizePublicKey 41 sizeSignature = 2 * sizeFr 42 ) 43 44 var order = fr.Modulus() 45 46 // PublicKey represents an ECDSA public key 47 type PublicKey struct { 48 A bls12378.G1Affine 49 } 50 51 // PrivateKey represents an ECDSA private key 52 type PrivateKey struct { 53 PublicKey PublicKey 54 scalar [sizeFr]byte // secret scalar, in big Endian 55 } 56 57 // Signature represents an ECDSA signature 58 type Signature struct { 59 R, S [sizeFr]byte 60 } 61 62 var one = new(big.Int).SetInt64(1) 63 64 // randFieldElement returns a random element of the order of the given 65 // curve using the procedure given in FIPS 186-4, Appendix B.5.1. 66 func randFieldElement(rand io.Reader) (k *big.Int, err error) { 67 b := make([]byte, fr.Bits/8+8) 68 _, err = io.ReadFull(rand, b) 69 if err != nil { 70 return 71 } 72 73 k = new(big.Int).SetBytes(b) 74 n := new(big.Int).Sub(order, one) 75 k.Mod(k, n) 76 k.Add(k, one) 77 return 78 } 79 80 // GenerateKey generates a public and private key pair. 81 func GenerateKey(rand io.Reader) (*PrivateKey, error) { 82 83 k, err := randFieldElement(rand) 84 if err != nil { 85 return nil, err 86 87 } 88 _, _, g, _ := bls12378.Generators() 89 90 privateKey := new(PrivateKey) 91 k.FillBytes(privateKey.scalar[:sizeFr]) 92 privateKey.PublicKey.A.ScalarMultiplication(&g, k) 93 return privateKey, nil 94 } 95 96 // HashToInt converts a hash value to an integer. Per FIPS 186-4, Section 6.4, 97 // we use the left-most bits of the hash to match the bit-length of the order of 98 // the curve. This also performs Step 5 of SEC 1, Version 2.0, Section 4.1.3. 99 func HashToInt(hash []byte) *big.Int { 100 if len(hash) > sizeFr { 101 hash = hash[:sizeFr] 102 } 103 ret := new(big.Int).SetBytes(hash) 104 excess := ret.BitLen() - sizeFrBits 105 if excess > 0 { 106 ret.Rsh(ret, uint(excess)) 107 } 108 return ret 109 } 110 111 type zr struct{} 112 113 // Read replaces the contents of dst with zeros. It is safe for concurrent use. 114 func (zr) Read(dst []byte) (n int, err error) { 115 for i := range dst { 116 dst[i] = 0 117 } 118 return len(dst), nil 119 } 120 121 var zeroReader = zr{} 122 123 const ( 124 aesIV = "gnark-crypto IV." // must be 16 chars (equal block size) 125 ) 126 127 func nonce(privateKey *PrivateKey, hash []byte) (csprng *cipher.StreamReader, err error) { 128 // This implementation derives the nonce from an AES-CTR CSPRNG keyed by: 129 // 130 // SHA2-512(privateKey.scalar ∥ entropy ∥ hash)[:32] 131 // 132 // The CSPRNG key is indifferentiable from a random oracle as shown in 133 // [Coron], the AES-CTR stream is indifferentiable from a random oracle 134 // under standard cryptographic assumptions (see [Larsson] for examples). 135 // 136 // [Coron]: https://cs.nyu.edu/~dodis/ps/merkle.pdf 137 // [Larsson]: https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf 138 139 // Get 256 bits of entropy from rand. 140 entropy := make([]byte, 32) 141 _, err = io.ReadFull(rand.Reader, entropy) 142 if err != nil { 143 return 144 145 } 146 147 // Initialize an SHA-512 hash context; digest... 148 md := sha512.New() 149 md.Write(privateKey.scalar[:sizeFr]) // the private key, 150 md.Write(entropy) // the entropy, 151 md.Write(hash) // and the input hash; 152 key := md.Sum(nil)[:32] // and compute ChopMD-256(SHA-512), 153 // which is an indifferentiable MAC. 154 155 // Create an AES-CTR instance to use as a CSPRNG. 156 block, _ := aes.NewCipher(key) 157 158 // Create a CSPRNG that xors a stream of zeros with 159 // the output of the AES-CTR instance. 160 csprng = &cipher.StreamReader{ 161 R: zeroReader, 162 S: cipher.NewCTR(block, []byte(aesIV)), 163 } 164 165 return csprng, err 166 } 167 168 // Equal compares 2 public keys 169 func (pub *PublicKey) Equal(x signature.PublicKey) bool { 170 xx, ok := x.(*PublicKey) 171 if !ok { 172 return false 173 } 174 bpk := pub.Bytes() 175 bxx := xx.Bytes() 176 return subtle.ConstantTimeCompare(bpk, bxx) == 1 177 } 178 179 // Public returns the public key associated to the private key. 180 func (privKey *PrivateKey) Public() signature.PublicKey { 181 var pub PublicKey 182 pub.A.Set(&privKey.PublicKey.A) 183 return &pub 184 } 185 186 // Sign performs the ECDSA signature 187 // 188 // k ← 𝔽r (random) 189 // P = k ⋅ g1Gen 190 // r = x_P (mod order) 191 // s = k⁻¹ . (m + sk ⋅ r) 192 // signature = {r, s} 193 // 194 // SEC 1, Version 2.0, Section 4.1.3 195 func (privKey *PrivateKey) Sign(message []byte, hFunc hash.Hash) ([]byte, error) { 196 scalar, r, s, kInv := new(big.Int), new(big.Int), new(big.Int), new(big.Int) 197 scalar.SetBytes(privKey.scalar[:sizeFr]) 198 for { 199 for { 200 csprng, err := nonce(privKey, message) 201 if err != nil { 202 return nil, err 203 } 204 k, err := randFieldElement(csprng) 205 if err != nil { 206 return nil, err 207 } 208 209 var P bls12378.G1Affine 210 P.ScalarMultiplicationBase(k) 211 kInv.ModInverse(k, order) 212 213 P.X.BigInt(r) 214 215 r.Mod(r, order) 216 if r.Sign() != 0 { 217 break 218 } 219 } 220 s.Mul(r, scalar) 221 222 var m *big.Int 223 if hFunc != nil { 224 // compute the hash of the message as an integer 225 dataToHash := make([]byte, len(message)) 226 copy(dataToHash[:], message[:]) 227 hFunc.Reset() 228 _, err := hFunc.Write(dataToHash[:]) 229 if err != nil { 230 return nil, err 231 } 232 hramBin := hFunc.Sum(nil) 233 m = HashToInt(hramBin) 234 } else { 235 m = HashToInt(message) 236 } 237 238 s.Add(m, s). 239 Mul(kInv, s). 240 Mod(s, order) // order != 0 241 if s.Sign() != 0 { 242 break 243 } 244 } 245 246 var sig Signature 247 r.FillBytes(sig.R[:sizeFr]) 248 s.FillBytes(sig.S[:sizeFr]) 249 250 return sig.Bytes(), nil 251 } 252 253 // Verify validates the ECDSA signature 254 // 255 // R ?= (s⁻¹ ⋅ m ⋅ Base + s⁻¹ ⋅ R ⋅ publiKey)_x 256 // 257 // SEC 1, Version 2.0, Section 4.1.4 258 func (publicKey *PublicKey) Verify(sigBin, message []byte, hFunc hash.Hash) (bool, error) { 259 260 // Deserialize the signature 261 var sig Signature 262 if _, err := sig.SetBytes(sigBin); err != nil { 263 return false, err 264 } 265 266 r, s := new(big.Int), new(big.Int) 267 r.SetBytes(sig.R[:sizeFr]) 268 s.SetBytes(sig.S[:sizeFr]) 269 270 sInv := new(big.Int).ModInverse(s, order) 271 272 var m *big.Int 273 if hFunc != nil { 274 // compute the hash of the message as an integer 275 dataToHash := make([]byte, len(message)) 276 copy(dataToHash[:], message[:]) 277 hFunc.Reset() 278 _, err := hFunc.Write(dataToHash[:]) 279 if err != nil { 280 return false, err 281 } 282 hramBin := hFunc.Sum(nil) 283 m = HashToInt(hramBin) 284 } else { 285 m = HashToInt(message) 286 } 287 288 u1 := new(big.Int).Mul(m, sInv) 289 u1.Mod(u1, order) 290 u2 := new(big.Int).Mul(r, sInv) 291 u2.Mod(u2, order) 292 var U bls12378.G1Jac 293 U.JointScalarMultiplicationBase(&publicKey.A, u1, u2) 294 295 var z big.Int 296 U.Z.Square(&U.Z). 297 Inverse(&U.Z). 298 Mul(&U.Z, &U.X). 299 BigInt(&z) 300 301 z.Mod(&z, order) 302 303 return z.Cmp(r) == 0, nil 304 305 }