* tree-vect-loop-manip.c (vect_do_peeling): Do not use
[official-gcc.git] / libgo / go / crypto / elliptic / elliptic.go
blobd3527243e78a4f5fc755a91ed556b5f266eab101
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.
5 // Package elliptic implements several standard elliptic curves over prime
6 // fields.
7 package elliptic
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.
16 import (
17 "io"
18 "math/big"
19 "sync"
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 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)
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 Name string // the canonical name of the curve
51 func (curve *CurveParams) Params() *CurveParams {
52 return curve
55 func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
56 // y² = x³ - 3x + b
57 y2 := new(big.Int).Mul(y, y)
58 y2.Mod(y2, curve.P)
60 x3 := new(big.Int).Mul(x, x)
61 x3.Mul(x3, x)
63 threeX := new(big.Int).Lsh(x, 1)
64 threeX.Add(threeX, x)
66 x3.Sub(x3, threeX)
67 x3.Add(x3, curve.B)
68 x3.Mod(x3, curve.P)
70 return x3.Cmp(y2) == 0
73 // zForAffine returns a Jacobian Z value for the affine point (x, y). If x and
74 // y are zero, it assumes that they represent the point at infinity because (0,
75 // 0) is not on the any of the curves handled here.
76 func zForAffine(x, y *big.Int) *big.Int {
77 z := new(big.Int)
78 if x.Sign() != 0 || y.Sign() != 0 {
79 z.SetInt64(1)
81 return z
84 // affineFromJacobian reverses the Jacobian transform. See the comment at the
85 // top of the file. If the point is ∞ it returns 0, 0.
86 func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
87 if z.Sign() == 0 {
88 return new(big.Int), new(big.Int)
91 zinv := new(big.Int).ModInverse(z, curve.P)
92 zinvsq := new(big.Int).Mul(zinv, zinv)
94 xOut = new(big.Int).Mul(x, zinvsq)
95 xOut.Mod(xOut, curve.P)
96 zinvsq.Mul(zinvsq, zinv)
97 yOut = new(big.Int).Mul(y, zinvsq)
98 yOut.Mod(yOut, curve.P)
99 return
102 func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
103 z1 := zForAffine(x1, y1)
104 z2 := zForAffine(x2, y2)
105 return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2))
108 // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
109 // (x2, y2, z2) and returns their sum, also in Jacobian form.
110 func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
111 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
112 x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int)
113 if z1.Sign() == 0 {
114 x3.Set(x2)
115 y3.Set(y2)
116 z3.Set(z2)
117 return x3, y3, z3
119 if z2.Sign() == 0 {
120 x3.Set(x1)
121 y3.Set(y1)
122 z3.Set(z1)
123 return x3, y3, z3
126 z1z1 := new(big.Int).Mul(z1, z1)
127 z1z1.Mod(z1z1, curve.P)
128 z2z2 := new(big.Int).Mul(z2, z2)
129 z2z2.Mod(z2z2, curve.P)
131 u1 := new(big.Int).Mul(x1, z2z2)
132 u1.Mod(u1, curve.P)
133 u2 := new(big.Int).Mul(x2, z1z1)
134 u2.Mod(u2, curve.P)
135 h := new(big.Int).Sub(u2, u1)
136 xEqual := h.Sign() == 0
137 if h.Sign() == -1 {
138 h.Add(h, curve.P)
140 i := new(big.Int).Lsh(h, 1)
141 i.Mul(i, i)
142 j := new(big.Int).Mul(h, i)
144 s1 := new(big.Int).Mul(y1, z2)
145 s1.Mul(s1, z2z2)
146 s1.Mod(s1, curve.P)
147 s2 := new(big.Int).Mul(y2, z1)
148 s2.Mul(s2, z1z1)
149 s2.Mod(s2, curve.P)
150 r := new(big.Int).Sub(s2, s1)
151 if r.Sign() == -1 {
152 r.Add(r, curve.P)
154 yEqual := r.Sign() == 0
155 if xEqual && yEqual {
156 return curve.doubleJacobian(x1, y1, z1)
158 r.Lsh(r, 1)
159 v := new(big.Int).Mul(u1, i)
161 x3.Set(r)
162 x3.Mul(x3, x3)
163 x3.Sub(x3, j)
164 x3.Sub(x3, v)
165 x3.Sub(x3, v)
166 x3.Mod(x3, curve.P)
168 y3.Set(r)
169 v.Sub(v, x3)
170 y3.Mul(y3, v)
171 s1.Mul(s1, j)
172 s1.Lsh(s1, 1)
173 y3.Sub(y3, s1)
174 y3.Mod(y3, curve.P)
176 z3.Add(z1, z2)
177 z3.Mul(z3, z3)
178 z3.Sub(z3, z1z1)
179 z3.Sub(z3, z2z2)
180 z3.Mul(z3, h)
181 z3.Mod(z3, curve.P)
183 return x3, y3, z3
186 func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
187 z1 := zForAffine(x1, y1)
188 return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
191 // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
192 // returns its double, also in Jacobian form.
193 func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
194 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
195 delta := new(big.Int).Mul(z, z)
196 delta.Mod(delta, curve.P)
197 gamma := new(big.Int).Mul(y, y)
198 gamma.Mod(gamma, curve.P)
199 alpha := new(big.Int).Sub(x, delta)
200 if alpha.Sign() == -1 {
201 alpha.Add(alpha, curve.P)
203 alpha2 := new(big.Int).Add(x, delta)
204 alpha.Mul(alpha, alpha2)
205 alpha2.Set(alpha)
206 alpha.Lsh(alpha, 1)
207 alpha.Add(alpha, alpha2)
209 beta := alpha2.Mul(x, gamma)
211 x3 := new(big.Int).Mul(alpha, alpha)
212 beta8 := new(big.Int).Lsh(beta, 3)
213 x3.Sub(x3, beta8)
214 for x3.Sign() == -1 {
215 x3.Add(x3, curve.P)
217 x3.Mod(x3, curve.P)
219 z3 := new(big.Int).Add(y, z)
220 z3.Mul(z3, z3)
221 z3.Sub(z3, gamma)
222 if z3.Sign() == -1 {
223 z3.Add(z3, curve.P)
225 z3.Sub(z3, delta)
226 if z3.Sign() == -1 {
227 z3.Add(z3, curve.P)
229 z3.Mod(z3, curve.P)
231 beta.Lsh(beta, 2)
232 beta.Sub(beta, x3)
233 if beta.Sign() == -1 {
234 beta.Add(beta, curve.P)
236 y3 := alpha.Mul(alpha, beta)
238 gamma.Mul(gamma, gamma)
239 gamma.Lsh(gamma, 3)
240 gamma.Mod(gamma, curve.P)
242 y3.Sub(y3, gamma)
243 if y3.Sign() == -1 {
244 y3.Add(y3, curve.P)
246 y3.Mod(y3, curve.P)
248 return x3, y3, z3
251 func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
252 Bz := new(big.Int).SetInt64(1)
253 x, y, z := new(big.Int), new(big.Int), new(big.Int)
255 for _, byte := range k {
256 for bitNum := 0; bitNum < 8; bitNum++ {
257 x, y, z = curve.doubleJacobian(x, y, z)
258 if byte&0x80 == 0x80 {
259 x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
261 byte <<= 1
265 return curve.affineFromJacobian(x, y, z)
268 func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
269 return curve.ScalarMult(curve.Gx, curve.Gy, k)
272 var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
274 // GenerateKey returns a public/private key pair. The private key is
275 // generated using the given reader, which must return random data.
276 func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
277 N := curve.Params().N
278 bitSize := N.BitLen()
279 byteLen := (bitSize + 7) >> 3
280 priv = make([]byte, byteLen)
282 for x == nil {
283 _, err = io.ReadFull(rand, priv)
284 if err != nil {
285 return
287 // We have to mask off any excess bits in the case that the size of the
288 // underlying field is not a whole number of bytes.
289 priv[0] &= mask[bitSize%8]
290 // This is because, in tests, rand will return all zeros and we don't
291 // want to get the point at infinity and loop forever.
292 priv[1] ^= 0x42
294 // If the scalar is out of range, sample another random number.
295 if new(big.Int).SetBytes(priv).Cmp(N) >= 0 {
296 continue
299 x, y = curve.ScalarBaseMult(priv)
301 return
304 // Marshal converts a point into the form specified in section 4.3.6 of ANSI X9.62.
305 func Marshal(curve Curve, x, y *big.Int) []byte {
306 byteLen := (curve.Params().BitSize + 7) >> 3
308 ret := make([]byte, 1+2*byteLen)
309 ret[0] = 4 // uncompressed point
311 xBytes := x.Bytes()
312 copy(ret[1+byteLen-len(xBytes):], xBytes)
313 yBytes := y.Bytes()
314 copy(ret[1+2*byteLen-len(yBytes):], yBytes)
315 return ret
318 // Unmarshal converts a point, serialized by Marshal, into an x, y pair.
319 // It is an error if the point is not on the curve. On error, x = nil.
320 func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
321 byteLen := (curve.Params().BitSize + 7) >> 3
322 if len(data) != 1+2*byteLen {
323 return
325 if data[0] != 4 { // uncompressed form
326 return
328 x = new(big.Int).SetBytes(data[1 : 1+byteLen])
329 y = new(big.Int).SetBytes(data[1+byteLen:])
330 if !curve.IsOnCurve(x, y) {
331 x, y = nil, nil
333 return
336 var initonce sync.Once
337 var p384 *CurveParams
338 var p521 *CurveParams
340 func initAll() {
341 initP224()
342 initP256()
343 initP384()
344 initP521()
347 func initP384() {
348 // See FIPS 186-3, section D.2.4
349 p384 = &CurveParams{Name: "P-384"}
350 p384.P, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319", 10)
351 p384.N, _ = new(big.Int).SetString("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643", 10)
352 p384.B, _ = new(big.Int).SetString("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef", 16)
353 p384.Gx, _ = new(big.Int).SetString("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", 16)
354 p384.Gy, _ = new(big.Int).SetString("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", 16)
355 p384.BitSize = 384
358 func initP521() {
359 // See FIPS 186-3, section D.2.5
360 p521 = &CurveParams{Name: "P-521"}
361 p521.P, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", 10)
362 p521.N, _ = new(big.Int).SetString("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449", 10)
363 p521.B, _ = new(big.Int).SetString("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 16)
364 p521.Gx, _ = new(big.Int).SetString("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 16)
365 p521.Gy, _ = new(big.Int).SetString("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 16)
366 p521.BitSize = 521
369 // P256 returns a Curve which implements P-256 (see FIPS 186-3, section D.2.3)
371 // The cryptographic operations are implemented using constant-time algorithms.
372 func P256() Curve {
373 initonce.Do(initAll)
374 return p256
377 // P384 returns a Curve which implements P-384 (see FIPS 186-3, section D.2.4)
379 // The cryptographic operations do not use constant-time algorithms.
380 func P384() Curve {
381 initonce.Do(initAll)
382 return p384
385 // P521 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5)
387 // The cryptographic operations do not use constant-time algorithms.
388 func P521() Curve {
389 initonce.Do(initAll)
390 return p521