Copyright 2010 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package elliptic implements several standard elliptic curves over prime fields.
package elliptic
This package operates, internally, on Jacobian coordinates. For a given (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole calculation can be performed within the transform (as in ScalarMult and ScalarBaseMult). But even for Add and Double, it's faster to apply and reverse the transform than to operate in affine coordinates.

import (
	
	
	
)
A Curve represents a short-form Weierstrass curve with a=-3. Note that the point at infinity (0, 0) is not considered on the curve, and although it can be returned by Add, Double, ScalarMult, or ScalarBaseMult, it can't be marshaled or unmarshaled, and IsOnCurve will return false for it.
Params returns the parameters for the curve.
IsOnCurve reports whether the given (x,y) lies on the curve.
Add returns the sum of (x1,y1) and (x2,y2)
Double returns 2*(x,y)
ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
ScalarBaseMult returns k*G, where G is the base point of the group and k is an integer in big-endian form.
	ScalarBaseMult(k []byte) (x, y *big.Int)
}
CurveParams contains the parameters of an elliptic curve and also provides a generic, non-constant time implementation of Curve.
type CurveParams struct {
	P       *big.Int // the order of the underlying field
	N       *big.Int // the order of the base point
	B       *big.Int // the constant of the curve equation
	Gx, Gy  *big.Int // (x,y) of the base point
	BitSize int      // the size of the underlying field
	Name    string   // the canonical name of the curve
}

func ( *CurveParams) () *CurveParams {
	return 
}
polynomial returns x³ - 3x + b.
func ( *CurveParams) ( *big.Int) *big.Int {
	 := new(big.Int).Mul(, )
	.Mul(, )

	 := new(big.Int).Lsh(, 1)
	.Add(, )

	.Sub(, )
	.Add(, .B)
	.Mod(, .P)

	return 
}

y² = x³ - 3x + b
	 := new(big.Int).Mul(, )
	.Mod(, .P)

	return .polynomial().Cmp() == 0
}
zForAffine returns a Jacobian Z value for the affine point (x, y). If x and y are zero, it assumes that they represent the point at infinity because (0, 0) is not on the any of the curves handled here.
func (,  *big.Int) *big.Int {
	 := new(big.Int)
	if .Sign() != 0 || .Sign() != 0 {
		.SetInt64(1)
	}
	return 
}
affineFromJacobian reverses the Jacobian transform. See the comment at the top of the file. If the point is ∞ it returns 0, 0.
func ( *CurveParams) (, ,  *big.Int) (,  *big.Int) {
	if .Sign() == 0 {
		return new(big.Int), new(big.Int)
	}

	 := new(big.Int).ModInverse(, .P)
	 := new(big.Int).Mul(, )

	 = new(big.Int).Mul(, )
	.Mod(, .P)
	.Mul(, )
	 = new(big.Int).Mul(, )
	.Mod(, .P)
	return
}

func ( *CurveParams) (, , ,  *big.Int) (*big.Int, *big.Int) {
	 := zForAffine(, )
	 := zForAffine(, )
	return .affineFromJacobian(.addJacobian(, , , , , ))
}
addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and (x2, y2, z2) and returns their sum, also in Jacobian form.
See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
	, ,  := new(big.Int), new(big.Int), new(big.Int)
	if .Sign() == 0 {
		.Set()
		.Set()
		.Set()
		return , , 
	}
	if .Sign() == 0 {
		.Set()
		.Set()
		.Set()
		return , , 
	}

	 := new(big.Int).Mul(, )
	.Mod(, .P)
	 := new(big.Int).Mul(, )
	.Mod(, .P)

	 := new(big.Int).Mul(, )
	.Mod(, .P)
	 := new(big.Int).Mul(, )
	.Mod(, .P)
	 := new(big.Int).Sub(, )
	 := .Sign() == 0
	if .Sign() == -1 {
		.Add(, .P)
	}
	 := new(big.Int).Lsh(, 1)
	.Mul(, )
	 := new(big.Int).Mul(, )

	 := new(big.Int).Mul(, )
	.Mul(, )
	.Mod(, .P)
	 := new(big.Int).Mul(, )
	.Mul(, )
	.Mod(, .P)
	 := new(big.Int).Sub(, )
	if .Sign() == -1 {
		.Add(, .P)
	}
	 := .Sign() == 0
	if  &&  {
		return .doubleJacobian(, , )
	}
	.Lsh(, 1)
	 := new(big.Int).Mul(, )

	.Set()
	.Mul(, )
	.Sub(, )
	.Sub(, )
	.Sub(, )
	.Mod(, .P)

	.Set()
	.Sub(, )
	.Mul(, )
	.Mul(, )
	.Lsh(, 1)
	.Sub(, )
	.Mod(, .P)

	.Add(, )
	.Mul(, )
	.Sub(, )
	.Sub(, )
	.Mul(, )
	.Mod(, .P)

	return , , 
}

func ( *CurveParams) (,  *big.Int) (*big.Int, *big.Int) {
	 := zForAffine(, )
	return .affineFromJacobian(.doubleJacobian(, , ))
}
doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and returns its double, also in Jacobian form.
See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
	 := new(big.Int).Mul(, )
	.Mod(, .P)
	 := new(big.Int).Mul(, )
	.Mod(, .P)
	 := new(big.Int).Sub(, )
	if .Sign() == -1 {
		.Add(, .P)
	}
	 := new(big.Int).Add(, )
	.Mul(, )
	.Set()
	.Lsh(, 1)
	.Add(, )

	 := .Mul(, )

	 := new(big.Int).Mul(, )
	 := new(big.Int).Lsh(, 3)
	.Mod(, .P)
	.Sub(, )
	if .Sign() == -1 {
		.Add(, .P)
	}
	.Mod(, .P)

	 := new(big.Int).Add(, )
	.Mul(, )
	.Sub(, )
	if .Sign() == -1 {
		.Add(, .P)
	}
	.Sub(, )
	if .Sign() == -1 {
		.Add(, .P)
	}
	.Mod(, .P)

	.Lsh(, 2)
	.Sub(, )
	if .Sign() == -1 {
		.Add(, .P)
	}
	 := .Mul(, )

	.Mul(, )
	.Lsh(, 3)
	.Mod(, .P)

	.Sub(, )
	if .Sign() == -1 {
		.Add(, .P)
	}
	.Mod(, .P)

	return , , 
}

func ( *CurveParams) (,  *big.Int,  []byte) (*big.Int, *big.Int) {
	 := new(big.Int).SetInt64(1)
	, ,  := new(big.Int), new(big.Int), new(big.Int)

	for ,  := range  {
		for  := 0;  < 8; ++ {
			, ,  = .doubleJacobian(, , )
			if &0x80 == 0x80 {
				, ,  = .addJacobian(, , , , , )
			}
			 <<= 1
		}
	}

	return .affineFromJacobian(, , )
}

func ( *CurveParams) ( []byte) (*big.Int, *big.Int) {
	return .ScalarMult(.Gx, .Gy, )
}

var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
GenerateKey returns a public/private key pair. The private key is generated using the given reader, which must return random data.
func ( Curve,  io.Reader) ( []byte, ,  *big.Int,  error) {
	 := .Params().N
	 := .BitLen()
	 := ( + 7) / 8
	 = make([]byte, )

	for  == nil {
		_,  = io.ReadFull(, )
		if  != nil {
			return
We have to mask off any excess bits in the case that the size of the underlying field is not a whole number of bytes.
This is because, in tests, rand will return all zeros and we don't want to get the point at infinity and loop forever.
		[1] ^= 0x42
If the scalar is out of range, sample another random number.
		if new(big.Int).SetBytes().Cmp() >= 0 {
			continue
		}

		,  = .ScalarBaseMult()
	}
	return
}
Marshal converts a point on the curve into the uncompressed form specified in section 4.3.6 of ANSI X9.62.
func ( Curve, ,  *big.Int) []byte {
	 := (.Params().BitSize + 7) / 8

	 := make([]byte, 1+2*)
	[0] = 4 // uncompressed point

	.FillBytes([1 : 1+])
	.FillBytes([1+ : 1+2*])

	return 
}
MarshalCompressed converts a point on the curve into the compressed form specified in section 4.3.6 of ANSI X9.62.
func ( Curve, ,  *big.Int) []byte {
	 := (.Params().BitSize + 7) / 8
	 := make([]byte, 1+)
	[0] = byte(.Bit(0)) | 2
	.FillBytes([1:])
	return 
}
Unmarshal converts a point, serialized by Marshal, into an x, y pair. It is an error if the point is not in uncompressed form or is not on the curve. On error, x = nil.
func ( Curve,  []byte) (,  *big.Int) {
	 := (.Params().BitSize + 7) / 8
	if len() != 1+2* {
		return nil, nil
	}
	if [0] != 4 { // uncompressed form
		return nil, nil
	}
	 := .Params().P
	 = new(big.Int).SetBytes([1 : 1+])
	 = new(big.Int).SetBytes([1+:])
	if .Cmp() >= 0 || .Cmp() >= 0 {
		return nil, nil
	}
	if !.IsOnCurve(, ) {
		return nil, nil
	}
	return
}
UnmarshalCompressed converts a point, serialized by MarshalCompressed, into an x, y pair. It is an error if the point is not in compressed form or is not on the curve. On error, x = nil.
func ( Curve,  []byte) (,  *big.Int) {
	 := (.Params().BitSize + 7) / 8
	if len() != 1+ {
		return nil, nil
	}
	if [0] != 2 && [0] != 3 { // compressed form
		return nil, nil
	}
	 := .Params().P
	 = new(big.Int).SetBytes([1:])
	if .Cmp() >= 0 {
		return nil, nil
y² = x³ - 3x + b
	 = .Params().polynomial()
	 = .ModSqrt(, )
	if  == nil {
		return nil, nil
	}
	if byte(.Bit(0)) != [0]&1 {
		.Neg().Mod(, )
	}
	if !.IsOnCurve(, ) {
		return nil, nil
	}
	return
}

var initonce sync.Once
var p384 *CurveParams
var p521 *CurveParams

func () {
	initP224()
	initP256()
	initP384()
	initP521()
}

See FIPS 186-3, section D.2.4
	p384 = &CurveParams{Name: "P-384"}
	p384.P, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319", 10)
	p384.N, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643", 10)
	p384.B, _ = new(big.Int).SetString("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16)
	p384.Gx, _ = new(big.Int).SetString("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", 16)
	p384.Gy, _ = new(big.Int).SetString("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", 16)
	p384.BitSize = 384
}

See FIPS 186-3, section D.2.5
	p521 = &CurveParams{Name: "P-521"}
	p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10)
	p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10)
	p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16)
	p521.Gx, _ = new(big.Int).SetString("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16)
	p521.Gy, _ = new(big.Int).SetString("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16)
	p521.BitSize = 521
}
P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3), also known as secp256r1 or prime256v1. The CurveParams.Name of this Curve is "P-256". Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements. The cryptographic operations are implemented using constant-time algorithms.
func () Curve {
	initonce.Do(initAll)
	return p256
}
P384 returns a Curve which implements NIST P-384 (FIPS 186-3, section D.2.4), also known as secp384r1. The CurveParams.Name of this Curve is "P-384". Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements. The cryptographic operations do not use constant-time algorithms.
func () Curve {
	initonce.Do(initAll)
	return p384
}
P521 returns a Curve which implements NIST P-521 (FIPS 186-3, section D.2.5), also known as secp521r1. The CurveParams.Name of this Curve is "P-521". Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements. The cryptographic operations do not use constant-time algorithms.
func () Curve {
	initonce.Do(initAll)
	return p521