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  }