github.com/FISCO-BCOS/crypto@v0.0.0-20200202032121-bd8ab0b5d4f1/elliptic/elliptic.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package elliptic implements several standard elliptic curves over prime 6 // fields. 7 package elliptic 8 9 // This package operates, internally, on Jacobian coordinates. For a given 10 // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) 11 // where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole 12 // calculation can be performed within the transform (as in ScalarMult and 13 // ScalarBaseMult). But even for Add and Double, it's faster to apply and 14 // reverse the transform than to operate in affine coordinates. 15 16 import ( 17 "io" 18 "math/big" 19 "sync" 20 ) 21 22 // A Curve represents a short-form Weierstrass curve with a=-3. 23 // See https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html 24 type Curve interface { 25 // Params returns the parameters for the curve. 26 Params() *CurveParams 27 // IsOnCurve reports whether the given (x,y) lies on the curve. 28 IsOnCurve(x, y *big.Int) bool 29 // Add returns the sum of (x1,y1) and (x2,y2) 30 Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) 31 // Double returns 2*(x,y) 32 Double(x1, y1 *big.Int) (x, y *big.Int) 33 // ScalarMult returns k*(Bx,By) where k is a number in big-endian form. 34 ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int) 35 // ScalarBaseMult returns k*G, where G is the base point of the group 36 // and k is an integer in big-endian form. 37 ScalarBaseMult(k []byte) (x, y *big.Int) 38 } 39 40 // CurveParams contains the parameters of an elliptic curve and also provides 41 // a generic, non-constant time implementation of Curve. 42 type CurveParams struct { 43 P *big.Int // the order of the underlying field 44 N *big.Int // the order of the base point 45 A *big.Int // the coefficient of x in the curve equation 46 B *big.Int // the constant of the curve equation 47 Gx, Gy *big.Int // (x,y) of the base point 48 BitSize int // the size of the underlying field 49 Name string // the canonical name of the curve 50 } 51 52 // Params returns the elliptic CurveParams of the implemented curve. 53 func (curve *CurveParams) Params() *CurveParams { 54 return curve 55 } 56 57 // IsOnCurve returns whether or not a (x, y) point is on the curve. 58 func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool { 59 // y² = x³ + ax + b 60 y2 := new(big.Int).Mul(y, y) 61 y2.Mod(y2, curve.P) 62 63 x3 := new(big.Int).Mul(x, x) 64 x3.Mul(x3, x) 65 66 aX := new(big.Int).Mul(curve.A, x) 67 aX.Mod(aX, curve.P) 68 69 x3.Add(x3, aX) 70 x3.Add(x3, curve.B) 71 x3.Mod(x3, curve.P) 72 73 return x3.Cmp(y2) == 0 74 } 75 76 // zForAffine returns a Jacobian Z value for the affine point (x, y). If x and 77 // y are zero, it assumes that they represent the point at infinity because (0, 78 // 0) is not on the any of the curves handled here. 79 func zForAffine(x, y *big.Int) *big.Int { 80 z := new(big.Int) 81 if x.Sign() != 0 || y.Sign() != 0 { 82 z.SetInt64(1) 83 } 84 return z 85 } 86 87 // affineFromJacobian reverses the Jacobian transform. See the comment at the 88 // top of the file. If the point is ∞ it returns 0, 0. 89 func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 90 if z.Sign() == 0 { 91 return new(big.Int), new(big.Int) 92 } 93 94 zinv := new(big.Int).ModInverse(z, curve.P) 95 zinvsq := new(big.Int).Mul(zinv, zinv) 96 97 xOut = new(big.Int).Mul(x, zinvsq) 98 xOut.Mod(xOut, curve.P) 99 zinvsq.Mul(zinvsq, zinv) 100 yOut = new(big.Int).Mul(y, zinvsq) 101 yOut.Mod(yOut, curve.P) 102 return 103 } 104 105 // Add returns the sum of two affine points. 106 func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 107 z1 := zForAffine(x1, y1) 108 z2 := zForAffine(x2, y2) 109 return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2)) 110 } 111 112 // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and 113 // (x2, y2, z2) and returns their sum, also in Jacobian form. 114 func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 115 // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl 116 x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int) 117 if z1.Sign() == 0 { 118 x3.Set(x2) 119 y3.Set(y2) 120 z3.Set(z2) 121 return x3, y3, z3 122 } 123 if z2.Sign() == 0 { 124 x3.Set(x1) 125 y3.Set(y1) 126 z3.Set(z1) 127 return x3, y3, z3 128 } 129 130 z1z1 := new(big.Int).Mul(z1, z1) 131 z1z1.Mod(z1z1, curve.P) 132 z2z2 := new(big.Int).Mul(z2, z2) 133 z2z2.Mod(z2z2, curve.P) 134 135 u1 := new(big.Int).Mul(x1, z2z2) 136 u1.Mod(u1, curve.P) 137 u2 := new(big.Int).Mul(x2, z1z1) 138 u2.Mod(u2, curve.P) 139 h := new(big.Int).Sub(u2, u1) 140 xEqual := h.Sign() == 0 141 if h.Sign() == -1 { 142 h.Add(h, curve.P) 143 } 144 i := new(big.Int).Lsh(h, 1) 145 i.Mul(i, i) 146 j := new(big.Int).Mul(h, i) 147 148 s1 := new(big.Int).Mul(y1, z2) 149 s1.Mul(s1, z2z2) 150 s1.Mod(s1, curve.P) 151 s2 := new(big.Int).Mul(y2, z1) 152 s2.Mul(s2, z1z1) 153 s2.Mod(s2, curve.P) 154 r := new(big.Int).Sub(s2, s1) 155 if r.Sign() == -1 { 156 r.Add(r, curve.P) 157 } 158 yEqual := r.Sign() == 0 159 if xEqual && yEqual { 160 return curve.doubleJacobian(x1, y1, z1) 161 } 162 r.Lsh(r, 1) 163 v := new(big.Int).Mul(u1, i) 164 165 x3.Set(r) 166 x3.Mul(x3, x3) 167 x3.Sub(x3, j) 168 x3.Sub(x3, v) 169 x3.Sub(x3, v) 170 x3.Mod(x3, curve.P) 171 172 y3.Set(r) 173 v.Sub(v, x3) 174 y3.Mul(y3, v) 175 s1.Mul(s1, j) 176 s1.Lsh(s1, 1) 177 y3.Sub(y3, s1) 178 y3.Mod(y3, curve.P) 179 180 z3.Add(z1, z2) 181 z3.Mul(z3, z3) 182 z3.Sub(z3, z1z1) 183 z3.Sub(z3, z2z2) 184 z3.Mul(z3, h) 185 z3.Mod(z3, curve.P) 186 187 return x3, y3, z3 188 } 189 190 // Double returns the double of an affine point. 191 func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 192 z1 := zForAffine(x1, y1) 193 return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1)) 194 } 195 196 // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and 197 // returns its double, also in Jacobian form. 198 func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 199 // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl 200 xx := new(big.Int).Mul(x, x) 201 xx.Mod(xx, curve.P) 202 203 yy := new(big.Int).Mul(y, y) 204 yy.Mod(yy, curve.P) 205 206 yyyy := new(big.Int).Mul(yy, yy) 207 yyyy.Mod(yyyy, curve.P) 208 209 zz := new(big.Int).Mul(z, z) 210 zz.Mod(zz, curve.P) 211 212 s := new(big.Int).Add(x, yy) 213 s.Mul(s, s) 214 s.Sub(s, xx) 215 if s.Sign() == -1 { 216 s.Add(s, curve.P) 217 } 218 s.Sub(s, yyyy) 219 if s.Sign() == -1 { 220 s.Add(s, curve.P) 221 } 222 s.Lsh(s, 1) 223 s.Mod(s, curve.P) 224 225 m := new(big.Int).Lsh(xx, 1) 226 m.Add(m, xx) 227 m2 := new(big.Int).Mul(zz, zz) 228 m2.Mul(curve.A, m2) 229 m.Add(m, m2) 230 m.Mod(m, curve.P) 231 232 t := new(big.Int).Mul(m, m) 233 t2 := new(big.Int).Lsh(s, 1) 234 t.Sub(t, t2) 235 if t.Sign() == -1 { 236 t.Add(t, curve.P) 237 } 238 t.Mod(t, curve.P) 239 240 x3 := new(big.Int).Set(t) 241 242 y3 := new(big.Int).Sub(s, t) 243 if y3.Sign() == -1 { 244 y3.Add(y3, curve.P) 245 } 246 y3.Mul(y3, m) 247 yyyy8 := new(big.Int).Lsh(yyyy, 3) 248 y3.Sub(y3, yyyy8) 249 if y3.Sign() == -1 { 250 y3.Add(y3, curve.P) 251 } 252 y3.Mod(y3, curve.P) 253 254 z3 := new(big.Int).Add(y, z) 255 z3.Mul(z3, z3) 256 z3.Sub(z3, yy) 257 if z3.Sign() == -1 { 258 z3.Add(z3, curve.P) 259 } 260 z3.Sub(z3, zz) 261 if z3.Sign() == -1 { 262 z3.Add(z3, curve.P) 263 } 264 z3.Mod(z3, curve.P) 265 266 return x3, y3, z3 267 } 268 269 // ScalarMult multiplies the point (Bx, By) by the scalar k using repeated doubling. 270 func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { 271 Bz := new(big.Int).SetInt64(1) 272 x, y, z := new(big.Int), new(big.Int), new(big.Int) 273 274 for _, byte := range k { 275 for bitNum := 0; bitNum < 8; bitNum++ { 276 x, y, z = curve.doubleJacobian(x, y, z) 277 if byte&0x80 == 0x80 { 278 x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z) 279 } 280 byte <<= 1 281 } 282 } 283 284 return curve.affineFromJacobian(x, y, z) 285 } 286 287 // ScalarBaseMult multiplies the base point by the scalar k using repeated doubling. 288 func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 289 return curve.ScalarMult(curve.Gx, curve.Gy, k) 290 } 291 292 var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f} 293 294 // GenerateKey returns a public/private key pair. The private key is 295 // generated using the given reader, which must return random data. 296 func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) { 297 N := curve.Params().N 298 bitSize := N.BitLen() 299 byteLen := (bitSize + 7) >> 3 300 priv = make([]byte, byteLen) 301 302 for x == nil { 303 _, err = io.ReadFull(rand, priv) 304 if err != nil { 305 return 306 } 307 // We have to mask off any excess bits in the case that the size of the 308 // underlying field is not a whole number of bytes. 309 priv[0] &= mask[bitSize%8] 310 // This is because, in tests, rand will return all zeros and we don't 311 // want to get the point at infinity and loop forever. 312 priv[1] ^= 0x42 313 314 // If the scalar is out of range, sample another random number. 315 if new(big.Int).SetBytes(priv).Cmp(N) >= 0 { 316 continue 317 } 318 319 x, y = curve.ScalarBaseMult(priv) 320 } 321 return 322 } 323 324 // Marshal converts a point into the uncompressed form specified in section 4.3.6 of ANSI X9.62. 325 func Marshal(curve Curve, x, y *big.Int) []byte { 326 byteLen := (curve.Params().BitSize + 7) >> 3 327 328 ret := make([]byte, 1+2*byteLen) 329 ret[0] = 4 // uncompressed point 330 331 xBytes := x.Bytes() 332 copy(ret[1+byteLen-len(xBytes):], xBytes) 333 yBytes := y.Bytes() 334 copy(ret[1+2*byteLen-len(yBytes):], yBytes) 335 return ret 336 } 337 338 // Unmarshal converts a point, serialized by Marshal, into an x, y pair. 339 // It is an error if the point is not in uncompressed form or is not on the curve. 340 // On error, x = nil. 341 func Unmarshal(curve Curve, data []byte) (x, y *big.Int) { 342 byteLen := (curve.Params().BitSize + 7) >> 3 343 if len(data) != 1+2*byteLen { 344 return 345 } 346 if data[0] != 4 { // uncompressed form 347 return 348 } 349 p := curve.Params().P 350 x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 351 y = new(big.Int).SetBytes(data[1+byteLen:]) 352 if x.Cmp(p) >= 0 || y.Cmp(p) >= 0 { 353 return nil, nil 354 } 355 if !curve.IsOnCurve(x, y) { 356 return nil, nil 357 } 358 return 359 } 360 361 var initonce sync.Once 362 var p384 *CurveParams 363 var p521 *CurveParams 364 365 func initAll() { 366 initP224() 367 initP256() 368 initP384() 369 initP521() 370 initSecp256k1() 371 InitSm2p256v1() 372 } 373 374 func initP384() { 375 // See FIPS 186-3, section D.2.4 376 p384 = &CurveParams{Name: "P-384"} 377 p384.P, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319", 10) 378 p384.N, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643", 10) 379 p384.A, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc", 16) 380 p384.B, _ = new(big.Int).SetString("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16) 381 p384.Gx, _ = new(big.Int).SetString("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", 16) 382 p384.Gy, _ = new(big.Int).SetString("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", 16) 383 p384.BitSize = 384 384 } 385 386 func initP521() { 387 // See FIPS 186-3, section D.2.5 388 p521 = &CurveParams{Name: "P-521"} 389 p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10) 390 p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10) 391 p521.A, _ = new(big.Int).SetString("01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", 16) 392 p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16) 393 p521.Gx, _ = new(big.Int).SetString("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16) 394 p521.Gy, _ = new(big.Int).SetString("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16) 395 p521.BitSize = 521 396 } 397 398 // P256 returns a Curve which implements P-256 (see FIPS 186-3, section D.2.3) 399 // 400 // The cryptographic operations are implemented using constant-time algorithms. 401 func P256() Curve { 402 initonce.Do(initAll) 403 return p256 404 } 405 406 // P384 returns a Curve which implements P-384 (see FIPS 186-3, section D.2.4) 407 // 408 // The cryptographic operations do not use constant-time algorithms. 409 func P384() Curve { 410 initonce.Do(initAll) 411 return p384 412 } 413 414 // P521 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5) 415 // 416 // The cryptographic operations do not use constant-time algorithms. 417 func P521() Curve { 418 initonce.Do(initAll) 419 return p521 420 }