github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/crypto/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 http://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 returns true if 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  	B       *big.Int // the constant of the curve equation
    46  	Gx, Gy  *big.Int // (x,y) of the base point
    47  	BitSize int      // the size of the underlying field
    48  }
    49  
    50  func (curve *CurveParams) Params() *CurveParams {
    51  	return curve
    52  }
    53  
    54  func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
    55  	// y² = x³ - 3x + b
    56  	y2 := new(big.Int).Mul(y, y)
    57  	y2.Mod(y2, curve.P)
    58  
    59  	x3 := new(big.Int).Mul(x, x)
    60  	x3.Mul(x3, x)
    61  
    62  	threeX := new(big.Int).Lsh(x, 1)
    63  	threeX.Add(threeX, x)
    64  
    65  	x3.Sub(x3, threeX)
    66  	x3.Add(x3, curve.B)
    67  	x3.Mod(x3, curve.P)
    68  
    69  	return x3.Cmp(y2) == 0
    70  }
    71  
    72  // zForAffine returns a Jacobian Z value for the affine point (x, y). If x and
    73  // y are zero, it assumes that they represent the point at infinity because (0,
    74  // 0) is not on the any of the curves handled here.
    75  func zForAffine(x, y *big.Int) *big.Int {
    76  	z := new(big.Int)
    77  	if x.Sign() != 0 || y.Sign() != 0 {
    78  		z.SetInt64(1)
    79  	}
    80  	return z
    81  }
    82  
    83  // affineFromJacobian reverses the Jacobian transform. See the comment at the
    84  // top of the file. If the point is ∞ it returns 0, 0.
    85  func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
    86  	if z.Sign() == 0 {
    87  		return new(big.Int), new(big.Int)
    88  	}
    89  
    90  	zinv := new(big.Int).ModInverse(z, curve.P)
    91  	zinvsq := new(big.Int).Mul(zinv, zinv)
    92  
    93  	xOut = new(big.Int).Mul(x, zinvsq)
    94  	xOut.Mod(xOut, curve.P)
    95  	zinvsq.Mul(zinvsq, zinv)
    96  	yOut = new(big.Int).Mul(y, zinvsq)
    97  	yOut.Mod(yOut, curve.P)
    98  	return
    99  }
   100  
   101  func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
   102  	z1 := zForAffine(x1, y1)
   103  	z2 := zForAffine(x2, y2)
   104  	return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2))
   105  }
   106  
   107  // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
   108  // (x2, y2, z2) and returns their sum, also in Jacobian form.
   109  func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
   110  	// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
   111  	x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int)
   112  	if z1.Sign() == 0 {
   113  		x3.Set(x2)
   114  		y3.Set(y2)
   115  		z3.Set(z2)
   116  		return x3, y3, z3
   117  	}
   118  	if z2.Sign() == 0 {
   119  		x3.Set(x1)
   120  		y3.Set(y1)
   121  		z3.Set(z1)
   122  		return x3, y3, z3
   123  	}
   124  
   125  	z1z1 := new(big.Int).Mul(z1, z1)
   126  	z1z1.Mod(z1z1, curve.P)
   127  	z2z2 := new(big.Int).Mul(z2, z2)
   128  	z2z2.Mod(z2z2, curve.P)
   129  
   130  	u1 := new(big.Int).Mul(x1, z2z2)
   131  	u1.Mod(u1, curve.P)
   132  	u2 := new(big.Int).Mul(x2, z1z1)
   133  	u2.Mod(u2, curve.P)
   134  	h := new(big.Int).Sub(u2, u1)
   135  	xEqual := h.Sign() == 0
   136  	if h.Sign() == -1 {
   137  		h.Add(h, curve.P)
   138  	}
   139  	i := new(big.Int).Lsh(h, 1)
   140  	i.Mul(i, i)
   141  	j := new(big.Int).Mul(h, i)
   142  
   143  	s1 := new(big.Int).Mul(y1, z2)
   144  	s1.Mul(s1, z2z2)
   145  	s1.Mod(s1, curve.P)
   146  	s2 := new(big.Int).Mul(y2, z1)
   147  	s2.Mul(s2, z1z1)
   148  	s2.Mod(s2, curve.P)
   149  	r := new(big.Int).Sub(s2, s1)
   150  	if r.Sign() == -1 {
   151  		r.Add(r, curve.P)
   152  	}
   153  	yEqual := r.Sign() == 0
   154  	if xEqual && yEqual {
   155  		return curve.doubleJacobian(x1, y1, z1)
   156  	}
   157  	r.Lsh(r, 1)
   158  	v := new(big.Int).Mul(u1, i)
   159  
   160  	x3.Set(r)
   161  	x3.Mul(x3, x3)
   162  	x3.Sub(x3, j)
   163  	x3.Sub(x3, v)
   164  	x3.Sub(x3, v)
   165  	x3.Mod(x3, curve.P)
   166  
   167  	y3.Set(r)
   168  	v.Sub(v, x3)
   169  	y3.Mul(y3, v)
   170  	s1.Mul(s1, j)
   171  	s1.Lsh(s1, 1)
   172  	y3.Sub(y3, s1)
   173  	y3.Mod(y3, curve.P)
   174  
   175  	z3.Add(z1, z2)
   176  	z3.Mul(z3, z3)
   177  	z3.Sub(z3, z1z1)
   178  	z3.Sub(z3, z2z2)
   179  	z3.Mul(z3, h)
   180  	z3.Mod(z3, curve.P)
   181  
   182  	return x3, y3, z3
   183  }
   184  
   185  func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
   186  	z1 := zForAffine(x1, y1)
   187  	return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
   188  }
   189  
   190  // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
   191  // returns its double, also in Jacobian form.
   192  func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
   193  	// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
   194  	delta := new(big.Int).Mul(z, z)
   195  	delta.Mod(delta, curve.P)
   196  	gamma := new(big.Int).Mul(y, y)
   197  	gamma.Mod(gamma, curve.P)
   198  	alpha := new(big.Int).Sub(x, delta)
   199  	if alpha.Sign() == -1 {
   200  		alpha.Add(alpha, curve.P)
   201  	}
   202  	alpha2 := new(big.Int).Add(x, delta)
   203  	alpha.Mul(alpha, alpha2)
   204  	alpha2.Set(alpha)
   205  	alpha.Lsh(alpha, 1)
   206  	alpha.Add(alpha, alpha2)
   207  
   208  	beta := alpha2.Mul(x, gamma)
   209  
   210  	x3 := new(big.Int).Mul(alpha, alpha)
   211  	beta8 := new(big.Int).Lsh(beta, 3)
   212  	x3.Sub(x3, beta8)
   213  	for x3.Sign() == -1 {
   214  		x3.Add(x3, curve.P)
   215  	}
   216  	x3.Mod(x3, curve.P)
   217  
   218  	z3 := new(big.Int).Add(y, z)
   219  	z3.Mul(z3, z3)
   220  	z3.Sub(z3, gamma)
   221  	if z3.Sign() == -1 {
   222  		z3.Add(z3, curve.P)
   223  	}
   224  	z3.Sub(z3, delta)
   225  	if z3.Sign() == -1 {
   226  		z3.Add(z3, curve.P)
   227  	}
   228  	z3.Mod(z3, curve.P)
   229  
   230  	beta.Lsh(beta, 2)
   231  	beta.Sub(beta, x3)
   232  	if beta.Sign() == -1 {
   233  		beta.Add(beta, curve.P)
   234  	}
   235  	y3 := alpha.Mul(alpha, beta)
   236  
   237  	gamma.Mul(gamma, gamma)
   238  	gamma.Lsh(gamma, 3)
   239  	gamma.Mod(gamma, curve.P)
   240  
   241  	y3.Sub(y3, gamma)
   242  	if y3.Sign() == -1 {
   243  		y3.Add(y3, curve.P)
   244  	}
   245  	y3.Mod(y3, curve.P)
   246  
   247  	return x3, y3, z3
   248  }
   249  
   250  func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
   251  	Bz := new(big.Int).SetInt64(1)
   252  	x, y, z := new(big.Int), new(big.Int), new(big.Int)
   253  
   254  	for _, byte := range k {
   255  		for bitNum := 0; bitNum < 8; bitNum++ {
   256  			x, y, z = curve.doubleJacobian(x, y, z)
   257  			if byte&0x80 == 0x80 {
   258  				x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
   259  			}
   260  			byte <<= 1
   261  		}
   262  	}
   263  
   264  	return curve.affineFromJacobian(x, y, z)
   265  }
   266  
   267  func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
   268  	return curve.ScalarMult(curve.Gx, curve.Gy, k)
   269  }
   270  
   271  var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
   272  
   273  // GenerateKey returns a public/private key pair. The private key is
   274  // generated using the given reader, which must return random data.
   275  func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
   276  	bitSize := curve.Params().BitSize
   277  	byteLen := (bitSize + 7) >> 3
   278  	priv = make([]byte, byteLen)
   279  
   280  	for x == nil {
   281  		_, err = io.ReadFull(rand, priv)
   282  		if err != nil {
   283  			return
   284  		}
   285  		// We have to mask off any excess bits in the case that the size of the
   286  		// underlying field is not a whole number of bytes.
   287  		priv[0] &= mask[bitSize%8]
   288  		// This is because, in tests, rand will return all zeros and we don't
   289  		// want to get the point at infinity and loop forever.
   290  		priv[1] ^= 0x42
   291  		x, y = curve.ScalarBaseMult(priv)
   292  	}
   293  	return
   294  }
   295  
   296  // Marshal converts a point into the form specified in section 4.3.6 of ANSI X9.62.
   297  func Marshal(curve Curve, x, y *big.Int) []byte {
   298  	byteLen := (curve.Params().BitSize + 7) >> 3
   299  
   300  	ret := make([]byte, 1+2*byteLen)
   301  	ret[0] = 4 // uncompressed point
   302  
   303  	xBytes := x.Bytes()
   304  	copy(ret[1+byteLen-len(xBytes):], xBytes)
   305  	yBytes := y.Bytes()
   306  	copy(ret[1+2*byteLen-len(yBytes):], yBytes)
   307  	return ret
   308  }
   309  
   310  // Unmarshal converts a point, serialized by Marshal, into an x, y pair. On error, x = nil.
   311  func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
   312  	byteLen := (curve.Params().BitSize + 7) >> 3
   313  	if len(data) != 1+2*byteLen {
   314  		return
   315  	}
   316  	if data[0] != 4 { // uncompressed form
   317  		return
   318  	}
   319  	x = new(big.Int).SetBytes(data[1 : 1+byteLen])
   320  	y = new(big.Int).SetBytes(data[1+byteLen:])
   321  	return
   322  }
   323  
   324  var initonce sync.Once
   325  var p384 *CurveParams
   326  var p521 *CurveParams
   327  
   328  func initAll() {
   329  	initP224()
   330  	initP256()
   331  	initP384()
   332  	initP521()
   333  }
   334  
   335  func initP384() {
   336  	// See FIPS 186-3, section D.2.4
   337  	p384 = new(CurveParams)
   338  	p384.P, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319", 10)
   339  	p384.N, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643", 10)
   340  	p384.B, _ = new(big.Int).SetString("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16)
   341  	p384.Gx, _ = new(big.Int).SetString("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", 16)
   342  	p384.Gy, _ = new(big.Int).SetString("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", 16)
   343  	p384.BitSize = 384
   344  }
   345  
   346  func initP521() {
   347  	// See FIPS 186-3, section D.2.5
   348  	p521 = new(CurveParams)
   349  	p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10)
   350  	p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10)
   351  	p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16)
   352  	p521.Gx, _ = new(big.Int).SetString("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16)
   353  	p521.Gy, _ = new(big.Int).SetString("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16)
   354  	p521.BitSize = 521
   355  }
   356  
   357  // P256 returns a Curve which implements P-256 (see FIPS 186-3, section D.2.3)
   358  func P256() Curve {
   359  	initonce.Do(initAll)
   360  	return p256
   361  }
   362  
   363  // P384 returns a Curve which implements P-384 (see FIPS 186-3, section D.2.4)
   364  func P384() Curve {
   365  	initonce.Do(initAll)
   366  	return p384
   367  }
   368  
   369  // P521 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5)
   370  func P521() Curve {
   371  	initonce.Do(initAll)
   372  	return p521
   373  }