@@ -36,295 +36,6 @@ type Curve interface {
36
36
ScalarBaseMult (k []byte ) (x , y * big.Int )
37
37
}
38
38
39
- func matchesSpecificCurve (params * CurveParams , available ... Curve ) (Curve , bool ) {
40
- for _ , c := range available {
41
- if params == c .Params () {
42
- return c , true
43
- }
44
- }
45
- return nil , false
46
- }
47
-
48
- // CurveParams contains the parameters of an elliptic curve and also provides
49
- // a generic, non-constant time implementation of Curve.
50
- type CurveParams struct {
51
- P * big.Int // the order of the underlying field
52
- N * big.Int // the order of the base point
53
- B * big.Int // the constant of the curve equation
54
- Gx , Gy * big.Int // (x,y) of the base point
55
- BitSize int // the size of the underlying field
56
- Name string // the canonical name of the curve
57
- }
58
-
59
- func (curve * CurveParams ) Params () * CurveParams {
60
- return curve
61
- }
62
-
63
- // CurveParams operates, internally, on Jacobian coordinates. For a given
64
- // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
65
- // where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
66
- // calculation can be performed within the transform (as in ScalarMult and
67
- // ScalarBaseMult). But even for Add and Double, it's faster to apply and
68
- // reverse the transform than to operate in affine coordinates.
69
-
70
- // polynomial returns x³ - 3x + b.
71
- func (curve * CurveParams ) polynomial (x * big.Int ) * big.Int {
72
- x3 := new (big.Int ).Mul (x , x )
73
- x3 .Mul (x3 , x )
74
-
75
- threeX := new (big.Int ).Lsh (x , 1 )
76
- threeX .Add (threeX , x )
77
-
78
- x3 .Sub (x3 , threeX )
79
- x3 .Add (x3 , curve .B )
80
- x3 .Mod (x3 , curve .P )
81
-
82
- return x3
83
- }
84
-
85
- func (curve * CurveParams ) IsOnCurve (x , y * big.Int ) bool {
86
- // If there is a dedicated constant-time implementation for this curve operation,
87
- // use that instead of the generic one.
88
- if specific , ok := matchesSpecificCurve (curve , p224 , p384 , p521 ); ok {
89
- return specific .IsOnCurve (x , y )
90
- }
91
-
92
- if x .Sign () < 0 || x .Cmp (curve .P ) >= 0 ||
93
- y .Sign () < 0 || y .Cmp (curve .P ) >= 0 {
94
- return false
95
- }
96
-
97
- // y² = x³ - 3x + b
98
- y2 := new (big.Int ).Mul (y , y )
99
- y2 .Mod (y2 , curve .P )
100
-
101
- return curve .polynomial (x ).Cmp (y2 ) == 0
102
- }
103
-
104
- // zForAffine returns a Jacobian Z value for the affine point (x, y). If x and
105
- // y are zero, it assumes that they represent the point at infinity because (0,
106
- // 0) is not on the any of the curves handled here.
107
- func zForAffine (x , y * big.Int ) * big.Int {
108
- z := new (big.Int )
109
- if x .Sign () != 0 || y .Sign () != 0 {
110
- z .SetInt64 (1 )
111
- }
112
- return z
113
- }
114
-
115
- // affineFromJacobian reverses the Jacobian transform. See the comment at the
116
- // top of the file. If the point is ∞ it returns 0, 0.
117
- func (curve * CurveParams ) affineFromJacobian (x , y , z * big.Int ) (xOut , yOut * big.Int ) {
118
- if z .Sign () == 0 {
119
- return new (big.Int ), new (big.Int )
120
- }
121
-
122
- zinv := new (big.Int ).ModInverse (z , curve .P )
123
- zinvsq := new (big.Int ).Mul (zinv , zinv )
124
-
125
- xOut = new (big.Int ).Mul (x , zinvsq )
126
- xOut .Mod (xOut , curve .P )
127
- zinvsq .Mul (zinvsq , zinv )
128
- yOut = new (big.Int ).Mul (y , zinvsq )
129
- yOut .Mod (yOut , curve .P )
130
- return
131
- }
132
-
133
- func (curve * CurveParams ) Add (x1 , y1 , x2 , y2 * big.Int ) (* big.Int , * big.Int ) {
134
- // If there is a dedicated constant-time implementation for this curve operation,
135
- // use that instead of the generic one.
136
- if specific , ok := matchesSpecificCurve (curve , p224 , p384 , p521 ); ok {
137
- return specific .Add (x1 , y1 , x2 , y2 )
138
- }
139
-
140
- z1 := zForAffine (x1 , y1 )
141
- z2 := zForAffine (x2 , y2 )
142
- return curve .affineFromJacobian (curve .addJacobian (x1 , y1 , z1 , x2 , y2 , z2 ))
143
- }
144
-
145
- // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
146
- // (x2, y2, z2) and returns their sum, also in Jacobian form.
147
- func (curve * CurveParams ) addJacobian (x1 , y1 , z1 , x2 , y2 , z2 * big.Int ) (* big.Int , * big.Int , * big.Int ) {
148
- // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
149
- x3 , y3 , z3 := new (big.Int ), new (big.Int ), new (big.Int )
150
- if z1 .Sign () == 0 {
151
- x3 .Set (x2 )
152
- y3 .Set (y2 )
153
- z3 .Set (z2 )
154
- return x3 , y3 , z3
155
- }
156
- if z2 .Sign () == 0 {
157
- x3 .Set (x1 )
158
- y3 .Set (y1 )
159
- z3 .Set (z1 )
160
- return x3 , y3 , z3
161
- }
162
-
163
- z1z1 := new (big.Int ).Mul (z1 , z1 )
164
- z1z1 .Mod (z1z1 , curve .P )
165
- z2z2 := new (big.Int ).Mul (z2 , z2 )
166
- z2z2 .Mod (z2z2 , curve .P )
167
-
168
- u1 := new (big.Int ).Mul (x1 , z2z2 )
169
- u1 .Mod (u1 , curve .P )
170
- u2 := new (big.Int ).Mul (x2 , z1z1 )
171
- u2 .Mod (u2 , curve .P )
172
- h := new (big.Int ).Sub (u2 , u1 )
173
- xEqual := h .Sign () == 0
174
- if h .Sign () == - 1 {
175
- h .Add (h , curve .P )
176
- }
177
- i := new (big.Int ).Lsh (h , 1 )
178
- i .Mul (i , i )
179
- j := new (big.Int ).Mul (h , i )
180
-
181
- s1 := new (big.Int ).Mul (y1 , z2 )
182
- s1 .Mul (s1 , z2z2 )
183
- s1 .Mod (s1 , curve .P )
184
- s2 := new (big.Int ).Mul (y2 , z1 )
185
- s2 .Mul (s2 , z1z1 )
186
- s2 .Mod (s2 , curve .P )
187
- r := new (big.Int ).Sub (s2 , s1 )
188
- if r .Sign () == - 1 {
189
- r .Add (r , curve .P )
190
- }
191
- yEqual := r .Sign () == 0
192
- if xEqual && yEqual {
193
- return curve .doubleJacobian (x1 , y1 , z1 )
194
- }
195
- r .Lsh (r , 1 )
196
- v := new (big.Int ).Mul (u1 , i )
197
-
198
- x3 .Set (r )
199
- x3 .Mul (x3 , x3 )
200
- x3 .Sub (x3 , j )
201
- x3 .Sub (x3 , v )
202
- x3 .Sub (x3 , v )
203
- x3 .Mod (x3 , curve .P )
204
-
205
- y3 .Set (r )
206
- v .Sub (v , x3 )
207
- y3 .Mul (y3 , v )
208
- s1 .Mul (s1 , j )
209
- s1 .Lsh (s1 , 1 )
210
- y3 .Sub (y3 , s1 )
211
- y3 .Mod (y3 , curve .P )
212
-
213
- z3 .Add (z1 , z2 )
214
- z3 .Mul (z3 , z3 )
215
- z3 .Sub (z3 , z1z1 )
216
- z3 .Sub (z3 , z2z2 )
217
- z3 .Mul (z3 , h )
218
- z3 .Mod (z3 , curve .P )
219
-
220
- return x3 , y3 , z3
221
- }
222
-
223
- func (curve * CurveParams ) Double (x1 , y1 * big.Int ) (* big.Int , * big.Int ) {
224
- // If there is a dedicated constant-time implementation for this curve operation,
225
- // use that instead of the generic one.
226
- if specific , ok := matchesSpecificCurve (curve , p224 , p384 , p521 ); ok {
227
- return specific .Double (x1 , y1 )
228
- }
229
-
230
- z1 := zForAffine (x1 , y1 )
231
- return curve .affineFromJacobian (curve .doubleJacobian (x1 , y1 , z1 ))
232
- }
233
-
234
- // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
235
- // returns its double, also in Jacobian form.
236
- func (curve * CurveParams ) doubleJacobian (x , y , z * big.Int ) (* big.Int , * big.Int , * big.Int ) {
237
- // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
238
- delta := new (big.Int ).Mul (z , z )
239
- delta .Mod (delta , curve .P )
240
- gamma := new (big.Int ).Mul (y , y )
241
- gamma .Mod (gamma , curve .P )
242
- alpha := new (big.Int ).Sub (x , delta )
243
- if alpha .Sign () == - 1 {
244
- alpha .Add (alpha , curve .P )
245
- }
246
- alpha2 := new (big.Int ).Add (x , delta )
247
- alpha .Mul (alpha , alpha2 )
248
- alpha2 .Set (alpha )
249
- alpha .Lsh (alpha , 1 )
250
- alpha .Add (alpha , alpha2 )
251
-
252
- beta := alpha2 .Mul (x , gamma )
253
-
254
- x3 := new (big.Int ).Mul (alpha , alpha )
255
- beta8 := new (big.Int ).Lsh (beta , 3 )
256
- beta8 .Mod (beta8 , curve .P )
257
- x3 .Sub (x3 , beta8 )
258
- if x3 .Sign () == - 1 {
259
- x3 .Add (x3 , curve .P )
260
- }
261
- x3 .Mod (x3 , curve .P )
262
-
263
- z3 := new (big.Int ).Add (y , z )
264
- z3 .Mul (z3 , z3 )
265
- z3 .Sub (z3 , gamma )
266
- if z3 .Sign () == - 1 {
267
- z3 .Add (z3 , curve .P )
268
- }
269
- z3 .Sub (z3 , delta )
270
- if z3 .Sign () == - 1 {
271
- z3 .Add (z3 , curve .P )
272
- }
273
- z3 .Mod (z3 , curve .P )
274
-
275
- beta .Lsh (beta , 2 )
276
- beta .Sub (beta , x3 )
277
- if beta .Sign () == - 1 {
278
- beta .Add (beta , curve .P )
279
- }
280
- y3 := alpha .Mul (alpha , beta )
281
-
282
- gamma .Mul (gamma , gamma )
283
- gamma .Lsh (gamma , 3 )
284
- gamma .Mod (gamma , curve .P )
285
-
286
- y3 .Sub (y3 , gamma )
287
- if y3 .Sign () == - 1 {
288
- y3 .Add (y3 , curve .P )
289
- }
290
- y3 .Mod (y3 , curve .P )
291
-
292
- return x3 , y3 , z3
293
- }
294
-
295
- func (curve * CurveParams ) ScalarMult (Bx , By * big.Int , k []byte ) (* big.Int , * big.Int ) {
296
- // If there is a dedicated constant-time implementation for this curve operation,
297
- // use that instead of the generic one.
298
- if specific , ok := matchesSpecificCurve (curve , p224 , p256 , p384 , p521 ); ok {
299
- return specific .ScalarMult (Bx , By , k )
300
- }
301
-
302
- Bz := new (big.Int ).SetInt64 (1 )
303
- x , y , z := new (big.Int ), new (big.Int ), new (big.Int )
304
-
305
- for _ , byte := range k {
306
- for bitNum := 0 ; bitNum < 8 ; bitNum ++ {
307
- x , y , z = curve .doubleJacobian (x , y , z )
308
- if byte & 0x80 == 0x80 {
309
- x , y , z = curve .addJacobian (Bx , By , Bz , x , y , z )
310
- }
311
- byte <<= 1
312
- }
313
- }
314
-
315
- return curve .affineFromJacobian (x , y , z )
316
- }
317
-
318
- func (curve * CurveParams ) ScalarBaseMult (k []byte ) (* big.Int , * big.Int ) {
319
- // If there is a dedicated constant-time implementation for this curve operation,
320
- // use that instead of the generic one.
321
- if specific , ok := matchesSpecificCurve (curve , p224 , p256 , p384 , p521 ); ok {
322
- return specific .ScalarBaseMult (k )
323
- }
324
-
325
- return curve .ScalarMult (curve .Gx , curve .Gy , k )
326
- }
327
-
328
39
var mask = []byte {0xff , 0x1 , 0x3 , 0x7 , 0xf , 0x1f , 0x3f , 0x7f }
329
40
330
41
// GenerateKey returns a public/private key pair. The private key is
0 commit comments