ec/asm/ecp_nistz256-*.pl: addition to perform stricter reduction.
[openssl.git] / crypto / ec / ecp_nistz256.c
1 /*
2  * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /******************************************************************************
11  *                                                                            *
12  * Copyright 2014 Intel Corporation                                           *
13  *                                                                            *
14  * Licensed under the Apache License, Version 2.0 (the "License");            *
15  * you may not use this file except in compliance with the License.           *
16  * You may obtain a copy of the License at                                    *
17  *                                                                            *
18  *    http://www.apache.org/licenses/LICENSE-2.0                              *
19  *                                                                            *
20  * Unless required by applicable law or agreed to in writing, software        *
21  * distributed under the License is distributed on an "AS IS" BASIS,          *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
23  * See the License for the specific language governing permissions and        *
24  * limitations under the License.                                             *
25  *                                                                            *
26  ******************************************************************************
27  *                                                                            *
28  * Developers and authors:                                                    *
29  * Shay Gueron (1, 2), and Vlad Krasnov (1)                                   *
30  * (1) Intel Corporation, Israel Development Center                           *
31  * (2) University of Haifa                                                    *
32  * Reference:                                                                 *
33  * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with *
34  *                          256 Bit Primes"                                   *
35  *                                                                            *
36  ******************************************************************************/
37
38 #include <string.h>
39
40 #include "internal/cryptlib.h"
41 #include "internal/bn_int.h"
42 #include "ec_lcl.h"
43
44 #if BN_BITS2 != 64
45 # define TOBN(hi,lo)    lo,hi
46 #else
47 # define TOBN(hi,lo)    ((BN_ULONG)hi<<32|lo)
48 #endif
49
50 #if defined(__GNUC__)
51 # define ALIGN32        __attribute((aligned(32)))
52 #elif defined(_MSC_VER)
53 # define ALIGN32        __declspec(align(32))
54 #else
55 # define ALIGN32
56 #endif
57
58 #define ALIGNPTR(p,N)   ((unsigned char *)p+N-(size_t)p%N)
59 #define P256_LIMBS      (256/BN_BITS2)
60
61 typedef unsigned short u16;
62
63 typedef struct {
64     BN_ULONG X[P256_LIMBS];
65     BN_ULONG Y[P256_LIMBS];
66     BN_ULONG Z[P256_LIMBS];
67 } P256_POINT;
68
69 typedef struct {
70     BN_ULONG X[P256_LIMBS];
71     BN_ULONG Y[P256_LIMBS];
72 } P256_POINT_AFFINE;
73
74 typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
75
76 /* structure for precomputed multiples of the generator */
77 struct nistz256_pre_comp_st {
78     const EC_GROUP *group;      /* Parent EC_GROUP object */
79     size_t w;                   /* Window size */
80     /*
81      * Constant time access to the X and Y coordinates of the pre-computed,
82      * generator multiplies, in the Montgomery domain. Pre-calculated
83      * multiplies are stored in affine form.
84      */
85     PRECOMP256_ROW *precomp;
86     void *precomp_storage;
87     int references;
88     CRYPTO_RWLOCK *lock;
89 };
90
91 /* Functions implemented in assembly */
92 /*
93  * Most of below mentioned functions *preserve* the property of inputs
94  * being fully reduced, i.e. being in [0, modulus) range. Simply put if
95  * inputs are fully reduced, then output is too. Note that reverse is
96  * not true, in sense that given partially reduced inputs output can be
97  * either, not unlikely reduced. And "most" in first sentence refers to
98  * the fact that given the calculations flow one can tolerate that
99  * addition, 1st function below, produces partially reduced result *if*
100  * multiplications by 2 and 3, which customarily use addition, fully
101  * reduce it. This effectively gives two options: a) addition produces
102  * fully reduced result [as long as inputs are, just like remaining
103  * functions]; b) addition is allowed to produce partially reduced
104  * result, but multiplications by 2 and 3 perform additional reduction
105  * step. Choice between the two can be platform-specific, but it was a)
106  * in all cases so far...
107  */
108 /* Modular add: res = a+b mod P   */
109 void ecp_nistz256_add(BN_ULONG res[P256_LIMBS],
110                       const BN_ULONG a[P256_LIMBS],
111                       const BN_ULONG b[P256_LIMBS]);
112 /* Modular mul by 2: res = 2*a mod P */
113 void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS],
114                            const BN_ULONG a[P256_LIMBS]);
115 /* Modular mul by 3: res = 3*a mod P */
116 void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS],
117                            const BN_ULONG a[P256_LIMBS]);
118
119 /* Modular div by 2: res = a/2 mod P */
120 void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS],
121                            const BN_ULONG a[P256_LIMBS]);
122 /* Modular sub: res = a-b mod P   */
123 void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS],
124                       const BN_ULONG a[P256_LIMBS],
125                       const BN_ULONG b[P256_LIMBS]);
126 /* Modular neg: res = -a mod P    */
127 void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
128 /* Montgomery mul: res = a*b*2^-256 mod P */
129 void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
130                            const BN_ULONG a[P256_LIMBS],
131                            const BN_ULONG b[P256_LIMBS]);
132 /* Montgomery sqr: res = a*a*2^-256 mod P */
133 void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
134                            const BN_ULONG a[P256_LIMBS]);
135 /* Convert a number from Montgomery domain, by multiplying with 1 */
136 void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
137                             const BN_ULONG in[P256_LIMBS]);
138 /* Convert a number to Montgomery domain, by multiplying with 2^512 mod P*/
139 void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS],
140                           const BN_ULONG in[P256_LIMBS]);
141 /* Functions that perform constant time access to the precomputed tables */
142 void ecp_nistz256_scatter_w5(P256_POINT *val,
143                              const P256_POINT *in_t, int idx);
144 void ecp_nistz256_gather_w5(P256_POINT *val,
145                             const P256_POINT *in_t, int idx);
146 void ecp_nistz256_scatter_w7(P256_POINT_AFFINE *val,
147                              const P256_POINT_AFFINE *in_t, int idx);
148 void ecp_nistz256_gather_w7(P256_POINT_AFFINE *val,
149                             const P256_POINT_AFFINE *in_t, int idx);
150
151 /* One converted into the Montgomery domain */
152 static const BN_ULONG ONE[P256_LIMBS] = {
153     TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000),
154     TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe)
155 };
156
157 static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group);
158
159 /* Precomputed tables for the default generator */
160 extern const PRECOMP256_ROW ecp_nistz256_precomputed[37];
161
162 /* Recode window to a signed digit, see ecp_nistputil.c for details */
163 static unsigned int _booth_recode_w5(unsigned int in)
164 {
165     unsigned int s, d;
166
167     s = ~((in >> 5) - 1);
168     d = (1 << 6) - in - 1;
169     d = (d & s) | (in & ~s);
170     d = (d >> 1) + (d & 1);
171
172     return (d << 1) + (s & 1);
173 }
174
175 static unsigned int _booth_recode_w7(unsigned int in)
176 {
177     unsigned int s, d;
178
179     s = ~((in >> 7) - 1);
180     d = (1 << 8) - in - 1;
181     d = (d & s) | (in & ~s);
182     d = (d >> 1) + (d & 1);
183
184     return (d << 1) + (s & 1);
185 }
186
187 static void copy_conditional(BN_ULONG dst[P256_LIMBS],
188                              const BN_ULONG src[P256_LIMBS], BN_ULONG move)
189 {
190     BN_ULONG mask1 = 0-move;
191     BN_ULONG mask2 = ~mask1;
192
193     dst[0] = (src[0] & mask1) ^ (dst[0] & mask2);
194     dst[1] = (src[1] & mask1) ^ (dst[1] & mask2);
195     dst[2] = (src[2] & mask1) ^ (dst[2] & mask2);
196     dst[3] = (src[3] & mask1) ^ (dst[3] & mask2);
197     if (P256_LIMBS == 8) {
198         dst[4] = (src[4] & mask1) ^ (dst[4] & mask2);
199         dst[5] = (src[5] & mask1) ^ (dst[5] & mask2);
200         dst[6] = (src[6] & mask1) ^ (dst[6] & mask2);
201         dst[7] = (src[7] & mask1) ^ (dst[7] & mask2);
202     }
203 }
204
205 static BN_ULONG is_zero(BN_ULONG in)
206 {
207     in |= (0 - in);
208     in = ~in;
209     in >>= BN_BITS2 - 1;
210     return in;
211 }
212
213 static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS],
214                          const BN_ULONG b[P256_LIMBS])
215 {
216     BN_ULONG res;
217
218     res = a[0] ^ b[0];
219     res |= a[1] ^ b[1];
220     res |= a[2] ^ b[2];
221     res |= a[3] ^ b[3];
222     if (P256_LIMBS == 8) {
223         res |= a[4] ^ b[4];
224         res |= a[5] ^ b[5];
225         res |= a[6] ^ b[6];
226         res |= a[7] ^ b[7];
227     }
228
229     return is_zero(res);
230 }
231
232 static BN_ULONG is_one(const BIGNUM *z)
233 {
234     BN_ULONG res = 0;
235     BN_ULONG *a = bn_get_words(z);
236
237     if (bn_get_top(z) == (P256_LIMBS - P256_LIMBS / 8)) {
238         res = a[0] ^ ONE[0];
239         res |= a[1] ^ ONE[1];
240         res |= a[2] ^ ONE[2];
241         res |= a[3] ^ ONE[3];
242         if (P256_LIMBS == 8) {
243             res |= a[4] ^ ONE[4];
244             res |= a[5] ^ ONE[5];
245             res |= a[6] ^ ONE[6];
246             /*
247              * no check for a[7] (being zero) on 32-bit platforms,
248              * because value of "one" takes only 7 limbs.
249              */
250         }
251         res = is_zero(res);
252     }
253
254     return res;
255 }
256
257 #ifndef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
258 void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
259 void ecp_nistz256_point_add(P256_POINT *r,
260                             const P256_POINT *a, const P256_POINT *b);
261 void ecp_nistz256_point_add_affine(P256_POINT *r,
262                                    const P256_POINT *a,
263                                    const P256_POINT_AFFINE *b);
264 #else
265 /* Point double: r = 2*a */
266 static void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a)
267 {
268     BN_ULONG S[P256_LIMBS];
269     BN_ULONG M[P256_LIMBS];
270     BN_ULONG Zsqr[P256_LIMBS];
271     BN_ULONG tmp0[P256_LIMBS];
272
273     const BN_ULONG *in_x = a->X;
274     const BN_ULONG *in_y = a->Y;
275     const BN_ULONG *in_z = a->Z;
276
277     BN_ULONG *res_x = r->X;
278     BN_ULONG *res_y = r->Y;
279     BN_ULONG *res_z = r->Z;
280
281     ecp_nistz256_mul_by_2(S, in_y);
282
283     ecp_nistz256_sqr_mont(Zsqr, in_z);
284
285     ecp_nistz256_sqr_mont(S, S);
286
287     ecp_nistz256_mul_mont(res_z, in_z, in_y);
288     ecp_nistz256_mul_by_2(res_z, res_z);
289
290     ecp_nistz256_add(M, in_x, Zsqr);
291     ecp_nistz256_sub(Zsqr, in_x, Zsqr);
292
293     ecp_nistz256_sqr_mont(res_y, S);
294     ecp_nistz256_div_by_2(res_y, res_y);
295
296     ecp_nistz256_mul_mont(M, M, Zsqr);
297     ecp_nistz256_mul_by_3(M, M);
298
299     ecp_nistz256_mul_mont(S, S, in_x);
300     ecp_nistz256_mul_by_2(tmp0, S);
301
302     ecp_nistz256_sqr_mont(res_x, M);
303
304     ecp_nistz256_sub(res_x, res_x, tmp0);
305     ecp_nistz256_sub(S, S, res_x);
306
307     ecp_nistz256_mul_mont(S, S, M);
308     ecp_nistz256_sub(res_y, S, res_y);
309 }
310
311 /* Point addition: r = a+b */
312 static void ecp_nistz256_point_add(P256_POINT *r,
313                                    const P256_POINT *a, const P256_POINT *b)
314 {
315     BN_ULONG U2[P256_LIMBS], S2[P256_LIMBS];
316     BN_ULONG U1[P256_LIMBS], S1[P256_LIMBS];
317     BN_ULONG Z1sqr[P256_LIMBS];
318     BN_ULONG Z2sqr[P256_LIMBS];
319     BN_ULONG H[P256_LIMBS], R[P256_LIMBS];
320     BN_ULONG Hsqr[P256_LIMBS];
321     BN_ULONG Rsqr[P256_LIMBS];
322     BN_ULONG Hcub[P256_LIMBS];
323
324     BN_ULONG res_x[P256_LIMBS];
325     BN_ULONG res_y[P256_LIMBS];
326     BN_ULONG res_z[P256_LIMBS];
327
328     BN_ULONG in1infty, in2infty;
329
330     const BN_ULONG *in1_x = a->X;
331     const BN_ULONG *in1_y = a->Y;
332     const BN_ULONG *in1_z = a->Z;
333
334     const BN_ULONG *in2_x = b->X;
335     const BN_ULONG *in2_y = b->Y;
336     const BN_ULONG *in2_z = b->Z;
337
338     /* We encode infinity as (0,0), which is not on the curve,
339      * so it is OK. */
340     in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] |
341                 in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]);
342     if (P256_LIMBS == 8)
343         in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] |
344                      in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]);
345
346     in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] |
347                 in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]);
348     if (P256_LIMBS == 8)
349         in2infty |= (in2_x[4] | in2_x[5] | in2_x[6] | in2_x[7] |
350                      in2_y[4] | in2_y[5] | in2_y[6] | in2_y[7]);
351
352     in1infty = is_zero(in1infty);
353     in2infty = is_zero(in2infty);
354
355     ecp_nistz256_sqr_mont(Z2sqr, in2_z);        /* Z2^2 */
356     ecp_nistz256_sqr_mont(Z1sqr, in1_z);        /* Z1^2 */
357
358     ecp_nistz256_mul_mont(S1, Z2sqr, in2_z);    /* S1 = Z2^3 */
359     ecp_nistz256_mul_mont(S2, Z1sqr, in1_z);    /* S2 = Z1^3 */
360
361     ecp_nistz256_mul_mont(S1, S1, in1_y);       /* S1 = Y1*Z2^3 */
362     ecp_nistz256_mul_mont(S2, S2, in2_y);       /* S2 = Y2*Z1^3 */
363     ecp_nistz256_sub(R, S2, S1);                /* R = S2 - S1 */
364
365     ecp_nistz256_mul_mont(U1, in1_x, Z2sqr);    /* U1 = X1*Z2^2 */
366     ecp_nistz256_mul_mont(U2, in2_x, Z1sqr);    /* U2 = X2*Z1^2 */
367     ecp_nistz256_sub(H, U2, U1);                /* H = U2 - U1 */
368
369     /*
370      * This should not happen during sign/ecdh, so no constant time violation
371      */
372     if (is_equal(U1, U2) && !in1infty && !in2infty) {
373         if (is_equal(S1, S2)) {
374             ecp_nistz256_point_double(r, a);
375             return;
376         } else {
377             memset(r, 0, sizeof(*r));
378             return;
379         }
380     }
381
382     ecp_nistz256_sqr_mont(Rsqr, R);             /* R^2 */
383     ecp_nistz256_mul_mont(res_z, H, in1_z);     /* Z3 = H*Z1*Z2 */
384     ecp_nistz256_sqr_mont(Hsqr, H);             /* H^2 */
385     ecp_nistz256_mul_mont(res_z, res_z, in2_z); /* Z3 = H*Z1*Z2 */
386     ecp_nistz256_mul_mont(Hcub, Hsqr, H);       /* H^3 */
387
388     ecp_nistz256_mul_mont(U2, U1, Hsqr);        /* U1*H^2 */
389     ecp_nistz256_mul_by_2(Hsqr, U2);            /* 2*U1*H^2 */
390
391     ecp_nistz256_sub(res_x, Rsqr, Hsqr);
392     ecp_nistz256_sub(res_x, res_x, Hcub);
393
394     ecp_nistz256_sub(res_y, U2, res_x);
395
396     ecp_nistz256_mul_mont(S2, S1, Hcub);
397     ecp_nistz256_mul_mont(res_y, R, res_y);
398     ecp_nistz256_sub(res_y, res_y, S2);
399
400     copy_conditional(res_x, in2_x, in1infty);
401     copy_conditional(res_y, in2_y, in1infty);
402     copy_conditional(res_z, in2_z, in1infty);
403
404     copy_conditional(res_x, in1_x, in2infty);
405     copy_conditional(res_y, in1_y, in2infty);
406     copy_conditional(res_z, in1_z, in2infty);
407
408     memcpy(r->X, res_x, sizeof(res_x));
409     memcpy(r->Y, res_y, sizeof(res_y));
410     memcpy(r->Z, res_z, sizeof(res_z));
411 }
412
413 /* Point addition when b is known to be affine: r = a+b */
414 static void ecp_nistz256_point_add_affine(P256_POINT *r,
415                                           const P256_POINT *a,
416                                           const P256_POINT_AFFINE *b)
417 {
418     BN_ULONG U2[P256_LIMBS], S2[P256_LIMBS];
419     BN_ULONG Z1sqr[P256_LIMBS];
420     BN_ULONG H[P256_LIMBS], R[P256_LIMBS];
421     BN_ULONG Hsqr[P256_LIMBS];
422     BN_ULONG Rsqr[P256_LIMBS];
423     BN_ULONG Hcub[P256_LIMBS];
424
425     BN_ULONG res_x[P256_LIMBS];
426     BN_ULONG res_y[P256_LIMBS];
427     BN_ULONG res_z[P256_LIMBS];
428
429     BN_ULONG in1infty, in2infty;
430
431     const BN_ULONG *in1_x = a->X;
432     const BN_ULONG *in1_y = a->Y;
433     const BN_ULONG *in1_z = a->Z;
434
435     const BN_ULONG *in2_x = b->X;
436     const BN_ULONG *in2_y = b->Y;
437
438     /*
439      * In affine representation we encode infty as (0,0), which is not on the
440      * curve, so it is OK
441      */
442     in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] |
443                 in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]);
444     if (P256_LIMBS == 8)
445         in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] |
446                      in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]);
447
448     in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] |
449                 in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]);
450     if (P256_LIMBS == 8)
451         in2infty |= (in2_x[4] | in2_x[5] | in2_x[6] | in2_x[7] |
452                      in2_y[4] | in2_y[5] | in2_y[6] | in2_y[7]);
453
454     in1infty = is_zero(in1infty);
455     in2infty = is_zero(in2infty);
456
457     ecp_nistz256_sqr_mont(Z1sqr, in1_z);        /* Z1^2 */
458
459     ecp_nistz256_mul_mont(U2, in2_x, Z1sqr);    /* U2 = X2*Z1^2 */
460     ecp_nistz256_sub(H, U2, in1_x);             /* H = U2 - U1 */
461
462     ecp_nistz256_mul_mont(S2, Z1sqr, in1_z);    /* S2 = Z1^3 */
463
464     ecp_nistz256_mul_mont(res_z, H, in1_z);     /* Z3 = H*Z1*Z2 */
465
466     ecp_nistz256_mul_mont(S2, S2, in2_y);       /* S2 = Y2*Z1^3 */
467     ecp_nistz256_sub(R, S2, in1_y);             /* R = S2 - S1 */
468
469     ecp_nistz256_sqr_mont(Hsqr, H);             /* H^2 */
470     ecp_nistz256_sqr_mont(Rsqr, R);             /* R^2 */
471     ecp_nistz256_mul_mont(Hcub, Hsqr, H);       /* H^3 */
472
473     ecp_nistz256_mul_mont(U2, in1_x, Hsqr);     /* U1*H^2 */
474     ecp_nistz256_mul_by_2(Hsqr, U2);            /* 2*U1*H^2 */
475
476     ecp_nistz256_sub(res_x, Rsqr, Hsqr);
477     ecp_nistz256_sub(res_x, res_x, Hcub);
478     ecp_nistz256_sub(H, U2, res_x);
479
480     ecp_nistz256_mul_mont(S2, in1_y, Hcub);
481     ecp_nistz256_mul_mont(H, H, R);
482     ecp_nistz256_sub(res_y, H, S2);
483
484     copy_conditional(res_x, in2_x, in1infty);
485     copy_conditional(res_x, in1_x, in2infty);
486
487     copy_conditional(res_y, in2_y, in1infty);
488     copy_conditional(res_y, in1_y, in2infty);
489
490     copy_conditional(res_z, ONE, in1infty);
491     copy_conditional(res_z, in1_z, in2infty);
492
493     memcpy(r->X, res_x, sizeof(res_x));
494     memcpy(r->Y, res_y, sizeof(res_y));
495     memcpy(r->Z, res_z, sizeof(res_z));
496 }
497 #endif
498
499 /* r = in^-1 mod p */
500 static void ecp_nistz256_mod_inverse(BN_ULONG r[P256_LIMBS],
501                                      const BN_ULONG in[P256_LIMBS])
502 {
503     /*
504      * The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff
505      * ffffffff ffffffff We use FLT and used poly-2 as exponent
506      */
507     BN_ULONG p2[P256_LIMBS];
508     BN_ULONG p4[P256_LIMBS];
509     BN_ULONG p8[P256_LIMBS];
510     BN_ULONG p16[P256_LIMBS];
511     BN_ULONG p32[P256_LIMBS];
512     BN_ULONG res[P256_LIMBS];
513     int i;
514
515     ecp_nistz256_sqr_mont(res, in);
516     ecp_nistz256_mul_mont(p2, res, in);         /* 3*p */
517
518     ecp_nistz256_sqr_mont(res, p2);
519     ecp_nistz256_sqr_mont(res, res);
520     ecp_nistz256_mul_mont(p4, res, p2);         /* f*p */
521
522     ecp_nistz256_sqr_mont(res, p4);
523     ecp_nistz256_sqr_mont(res, res);
524     ecp_nistz256_sqr_mont(res, res);
525     ecp_nistz256_sqr_mont(res, res);
526     ecp_nistz256_mul_mont(p8, res, p4);         /* ff*p */
527
528     ecp_nistz256_sqr_mont(res, p8);
529     for (i = 0; i < 7; i++)
530         ecp_nistz256_sqr_mont(res, res);
531     ecp_nistz256_mul_mont(p16, res, p8);        /* ffff*p */
532
533     ecp_nistz256_sqr_mont(res, p16);
534     for (i = 0; i < 15; i++)
535         ecp_nistz256_sqr_mont(res, res);
536     ecp_nistz256_mul_mont(p32, res, p16);       /* ffffffff*p */
537
538     ecp_nistz256_sqr_mont(res, p32);
539     for (i = 0; i < 31; i++)
540         ecp_nistz256_sqr_mont(res, res);
541     ecp_nistz256_mul_mont(res, res, in);
542
543     for (i = 0; i < 32 * 4; i++)
544         ecp_nistz256_sqr_mont(res, res);
545     ecp_nistz256_mul_mont(res, res, p32);
546
547     for (i = 0; i < 32; i++)
548         ecp_nistz256_sqr_mont(res, res);
549     ecp_nistz256_mul_mont(res, res, p32);
550
551     for (i = 0; i < 16; i++)
552         ecp_nistz256_sqr_mont(res, res);
553     ecp_nistz256_mul_mont(res, res, p16);
554
555     for (i = 0; i < 8; i++)
556         ecp_nistz256_sqr_mont(res, res);
557     ecp_nistz256_mul_mont(res, res, p8);
558
559     ecp_nistz256_sqr_mont(res, res);
560     ecp_nistz256_sqr_mont(res, res);
561     ecp_nistz256_sqr_mont(res, res);
562     ecp_nistz256_sqr_mont(res, res);
563     ecp_nistz256_mul_mont(res, res, p4);
564
565     ecp_nistz256_sqr_mont(res, res);
566     ecp_nistz256_sqr_mont(res, res);
567     ecp_nistz256_mul_mont(res, res, p2);
568
569     ecp_nistz256_sqr_mont(res, res);
570     ecp_nistz256_sqr_mont(res, res);
571     ecp_nistz256_mul_mont(res, res, in);
572
573     memcpy(r, res, sizeof(res));
574 }
575
576 /*
577  * ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and
578  * returns one if it fits. Otherwise it returns zero.
579  */
580 __owur static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS],
581                                                     const BIGNUM *in)
582 {
583     return bn_copy_words(out, in, P256_LIMBS);
584 }
585
586 /* r = sum(scalar[i]*point[i]) */
587 __owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group,
588                                             P256_POINT *r,
589                                             const BIGNUM **scalar,
590                                             const EC_POINT **point,
591                                             size_t num, BN_CTX *ctx)
592 {
593     size_t i;
594     int j, ret = 0;
595     unsigned int idx;
596     unsigned char (*p_str)[33] = NULL;
597     const unsigned int window_size = 5;
598     const unsigned int mask = (1 << (window_size + 1)) - 1;
599     unsigned int wvalue;
600     P256_POINT *temp;           /* place for 5 temporary points */
601     const BIGNUM **scalars = NULL;
602     P256_POINT (*table)[16] = NULL;
603     void *table_storage = NULL;
604
605     if ((num * 16 + 6) > OPENSSL_MALLOC_MAX_NELEMS(P256_POINT)
606         || (table_storage =
607             OPENSSL_malloc((num * 16 + 5) * sizeof(P256_POINT) + 64)) == NULL
608         || (p_str =
609             OPENSSL_malloc(num * 33 * sizeof(unsigned char))) == NULL
610         || (scalars = OPENSSL_malloc(num * sizeof(BIGNUM *))) == NULL) {
611         ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_MALLOC_FAILURE);
612         goto err;
613     }
614
615     table = (void *)ALIGNPTR(table_storage, 64);
616     temp = (P256_POINT *)(table + num);
617
618     for (i = 0; i < num; i++) {
619         P256_POINT *row = table[i];
620
621         /* This is an unusual input, we don't guarantee constant-timeness. */
622         if ((BN_num_bits(scalar[i]) > 256) || BN_is_negative(scalar[i])) {
623             BIGNUM *mod;
624
625             if ((mod = BN_CTX_get(ctx)) == NULL)
626                 goto err;
627             if (!BN_nnmod(mod, scalar[i], group->order, ctx)) {
628                 ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_BN_LIB);
629                 goto err;
630             }
631             scalars[i] = mod;
632         } else
633             scalars[i] = scalar[i];
634
635         for (j = 0; j < bn_get_top(scalars[i]) * BN_BYTES; j += BN_BYTES) {
636             BN_ULONG d = bn_get_words(scalars[i])[j / BN_BYTES];
637
638             p_str[i][j + 0] = (unsigned char)d;
639             p_str[i][j + 1] = (unsigned char)(d >> 8);
640             p_str[i][j + 2] = (unsigned char)(d >> 16);
641             p_str[i][j + 3] = (unsigned char)(d >>= 24);
642             if (BN_BYTES == 8) {
643                 d >>= 8;
644                 p_str[i][j + 4] = (unsigned char)d;
645                 p_str[i][j + 5] = (unsigned char)(d >> 8);
646                 p_str[i][j + 6] = (unsigned char)(d >> 16);
647                 p_str[i][j + 7] = (unsigned char)(d >> 24);
648             }
649         }
650         for (; j < 33; j++)
651             p_str[i][j] = 0;
652
653         if (!ecp_nistz256_bignum_to_field_elem(temp[0].X, point[i]->X)
654             || !ecp_nistz256_bignum_to_field_elem(temp[0].Y, point[i]->Y)
655             || !ecp_nistz256_bignum_to_field_elem(temp[0].Z, point[i]->Z)) {
656             ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL,
657                   EC_R_COORDINATES_OUT_OF_RANGE);
658             goto err;
659         }
660
661         /*
662          * row[0] is implicitly (0,0,0) (the point at infinity), therefore it
663          * is not stored. All other values are actually stored with an offset
664          * of -1 in table.
665          */
666
667         ecp_nistz256_scatter_w5  (row, &temp[0], 1);
668         ecp_nistz256_point_double(&temp[1], &temp[0]);              /*1+1=2  */
669         ecp_nistz256_scatter_w5  (row, &temp[1], 2);
670         ecp_nistz256_point_add   (&temp[2], &temp[1], &temp[0]);    /*2+1=3  */
671         ecp_nistz256_scatter_w5  (row, &temp[2], 3);
672         ecp_nistz256_point_double(&temp[1], &temp[1]);              /*2*2=4  */
673         ecp_nistz256_scatter_w5  (row, &temp[1], 4);
674         ecp_nistz256_point_double(&temp[2], &temp[2]);              /*2*3=6  */
675         ecp_nistz256_scatter_w5  (row, &temp[2], 6);
676         ecp_nistz256_point_add   (&temp[3], &temp[1], &temp[0]);    /*4+1=5  */
677         ecp_nistz256_scatter_w5  (row, &temp[3], 5);
678         ecp_nistz256_point_add   (&temp[4], &temp[2], &temp[0]);    /*6+1=7  */
679         ecp_nistz256_scatter_w5  (row, &temp[4], 7);
680         ecp_nistz256_point_double(&temp[1], &temp[1]);              /*2*4=8  */
681         ecp_nistz256_scatter_w5  (row, &temp[1], 8);
682         ecp_nistz256_point_double(&temp[2], &temp[2]);              /*2*6=12 */
683         ecp_nistz256_scatter_w5  (row, &temp[2], 12);
684         ecp_nistz256_point_double(&temp[3], &temp[3]);              /*2*5=10 */
685         ecp_nistz256_scatter_w5  (row, &temp[3], 10);
686         ecp_nistz256_point_double(&temp[4], &temp[4]);              /*2*7=14 */
687         ecp_nistz256_scatter_w5  (row, &temp[4], 14);
688         ecp_nistz256_point_add   (&temp[2], &temp[2], &temp[0]);    /*12+1=13*/
689         ecp_nistz256_scatter_w5  (row, &temp[2], 13);
690         ecp_nistz256_point_add   (&temp[3], &temp[3], &temp[0]);    /*10+1=11*/
691         ecp_nistz256_scatter_w5  (row, &temp[3], 11);
692         ecp_nistz256_point_add   (&temp[4], &temp[4], &temp[0]);    /*14+1=15*/
693         ecp_nistz256_scatter_w5  (row, &temp[4], 15);
694         ecp_nistz256_point_add   (&temp[2], &temp[1], &temp[0]);    /*8+1=9  */
695         ecp_nistz256_scatter_w5  (row, &temp[2], 9);
696         ecp_nistz256_point_double(&temp[1], &temp[1]);              /*2*8=16 */
697         ecp_nistz256_scatter_w5  (row, &temp[1], 16);
698     }
699
700     idx = 255;
701
702     wvalue = p_str[0][(idx - 1) / 8];
703     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
704
705     /*
706      * We gather to temp[0], because we know it's position relative
707      * to table
708      */
709     ecp_nistz256_gather_w5(&temp[0], table[0], _booth_recode_w5(wvalue) >> 1);
710     memcpy(r, &temp[0], sizeof(temp[0]));
711
712     while (idx >= 5) {
713         for (i = (idx == 255 ? 1 : 0); i < num; i++) {
714             unsigned int off = (idx - 1) / 8;
715
716             wvalue = p_str[i][off] | p_str[i][off + 1] << 8;
717             wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
718
719             wvalue = _booth_recode_w5(wvalue);
720
721             ecp_nistz256_gather_w5(&temp[0], table[i], wvalue >> 1);
722
723             ecp_nistz256_neg(temp[1].Y, temp[0].Y);
724             copy_conditional(temp[0].Y, temp[1].Y, (wvalue & 1));
725
726             ecp_nistz256_point_add(r, r, &temp[0]);
727         }
728
729         idx -= window_size;
730
731         ecp_nistz256_point_double(r, r);
732         ecp_nistz256_point_double(r, r);
733         ecp_nistz256_point_double(r, r);
734         ecp_nistz256_point_double(r, r);
735         ecp_nistz256_point_double(r, r);
736     }
737
738     /* Final window */
739     for (i = 0; i < num; i++) {
740         wvalue = p_str[i][0];
741         wvalue = (wvalue << 1) & mask;
742
743         wvalue = _booth_recode_w5(wvalue);
744
745         ecp_nistz256_gather_w5(&temp[0], table[i], wvalue >> 1);
746
747         ecp_nistz256_neg(temp[1].Y, temp[0].Y);
748         copy_conditional(temp[0].Y, temp[1].Y, wvalue & 1);
749
750         ecp_nistz256_point_add(r, r, &temp[0]);
751     }
752
753     ret = 1;
754  err:
755     OPENSSL_free(table_storage);
756     OPENSSL_free(p_str);
757     OPENSSL_free(scalars);
758     return ret;
759 }
760
761 /* Coordinates of G, for which we have precomputed tables */
762 const static BN_ULONG def_xG[P256_LIMBS] = {
763     TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
764     TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6)
765 };
766
767 const static BN_ULONG def_yG[P256_LIMBS] = {
768     TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
769     TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85)
770 };
771
772 /*
773  * ecp_nistz256_is_affine_G returns one if |generator| is the standard, P-256
774  * generator.
775  */
776 static int ecp_nistz256_is_affine_G(const EC_POINT *generator)
777 {
778     return (bn_get_top(generator->X) == P256_LIMBS) &&
779         (bn_get_top(generator->Y) == P256_LIMBS) &&
780         is_equal(bn_get_words(generator->X), def_xG) &&
781         is_equal(bn_get_words(generator->Y), def_yG) &&
782         is_one(generator->Z);
783 }
784
785 __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
786 {
787     /*
788      * We precompute a table for a Booth encoded exponent (wNAF) based
789      * computation. Each table holds 64 values for safe access, with an
790      * implicit value of infinity at index zero. We use window of size 7, and
791      * therefore require ceil(256/7) = 37 tables.
792      */
793     const BIGNUM *order;
794     EC_POINT *P = NULL, *T = NULL;
795     const EC_POINT *generator;
796     NISTZ256_PRE_COMP *pre_comp;
797     BN_CTX *new_ctx = NULL;
798     int i, j, k, ret = 0;
799     size_t w;
800
801     PRECOMP256_ROW *preComputedTable = NULL;
802     unsigned char *precomp_storage = NULL;
803
804     /* if there is an old NISTZ256_PRE_COMP object, throw it away */
805     EC_pre_comp_free(group);
806     generator = EC_GROUP_get0_generator(group);
807     if (generator == NULL) {
808         ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNDEFINED_GENERATOR);
809         return 0;
810     }
811
812     if (ecp_nistz256_is_affine_G(generator)) {
813         /*
814          * No need to calculate tables for the standard generator because we
815          * have them statically.
816          */
817         return 1;
818     }
819
820     if ((pre_comp = ecp_nistz256_pre_comp_new(group)) == NULL)
821         return 0;
822
823     if (ctx == NULL) {
824         ctx = new_ctx = BN_CTX_new();
825         if (ctx == NULL)
826             goto err;
827     }
828
829     BN_CTX_start(ctx);
830
831     order = EC_GROUP_get0_order(group);
832     if (order == NULL)
833         goto err;
834
835     if (BN_is_zero(order)) {
836         ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNKNOWN_ORDER);
837         goto err;
838     }
839
840     w = 7;
841
842     if ((precomp_storage =
843          OPENSSL_malloc(37 * 64 * sizeof(P256_POINT_AFFINE) + 64)) == NULL) {
844         ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, ERR_R_MALLOC_FAILURE);
845         goto err;
846     }
847
848     preComputedTable = (void *)ALIGNPTR(precomp_storage, 64);
849
850     P = EC_POINT_new(group);
851     T = EC_POINT_new(group);
852     if (P == NULL || T == NULL)
853         goto err;
854
855     /*
856      * The zero entry is implicitly infinity, and we skip it, storing other
857      * values with -1 offset.
858      */
859     if (!EC_POINT_copy(T, generator))
860         goto err;
861
862     for (k = 0; k < 64; k++) {
863         if (!EC_POINT_copy(P, T))
864             goto err;
865         for (j = 0; j < 37; j++) {
866             P256_POINT_AFFINE temp;
867             /*
868              * It would be faster to use EC_POINTs_make_affine and
869              * make multiple points affine at the same time.
870              */
871             if (!EC_POINT_make_affine(group, P, ctx))
872                 goto err;
873             if (!ecp_nistz256_bignum_to_field_elem(temp.X, P->X) ||
874                 !ecp_nistz256_bignum_to_field_elem(temp.Y, P->Y)) {
875                 ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE,
876                       EC_R_COORDINATES_OUT_OF_RANGE);
877                 goto err;
878             }
879             ecp_nistz256_scatter_w7(preComputedTable[j], &temp, k);
880             for (i = 0; i < 7; i++) {
881                 if (!EC_POINT_dbl(group, P, P, ctx))
882                     goto err;
883             }
884         }
885         if (!EC_POINT_add(group, T, T, generator, ctx))
886             goto err;
887     }
888
889     pre_comp->group = group;
890     pre_comp->w = w;
891     pre_comp->precomp = preComputedTable;
892     pre_comp->precomp_storage = precomp_storage;
893     precomp_storage = NULL;
894     SETPRECOMP(group, nistz256, pre_comp);
895     pre_comp = NULL;
896     ret = 1;
897
898  err:
899     if (ctx != NULL)
900         BN_CTX_end(ctx);
901     BN_CTX_free(new_ctx);
902
903     EC_nistz256_pre_comp_free(pre_comp);
904     OPENSSL_free(precomp_storage);
905     EC_POINT_free(P);
906     EC_POINT_free(T);
907     return ret;
908 }
909
910 /*
911  * Note that by default ECP_NISTZ256_AVX2 is undefined. While it's great
912  * code processing 4 points in parallel, corresponding serial operation
913  * is several times slower, because it uses 29x29=58-bit multiplication
914  * as opposite to 64x64=128-bit in integer-only scalar case. As result
915  * it doesn't provide *significant* performance improvement. Note that
916  * just defining ECP_NISTZ256_AVX2 is not sufficient to make it work,
917  * you'd need to compile even asm/ecp_nistz256-avx.pl module.
918  */
919 #if defined(ECP_NISTZ256_AVX2)
920 # if !(defined(__x86_64) || defined(__x86_64__) || \
921        defined(_M_AMD64) || defined(_MX64)) || \
922      !(defined(__GNUC__) || defined(_MSC_VER)) /* this is for ALIGN32 */
923 #  undef ECP_NISTZ256_AVX2
924 # else
925 /* Constant time access, loading four values, from four consecutive tables */
926 void ecp_nistz256_avx2_multi_gather_w7(void *result, const void *in,
927                                        int index0, int index1, int index2,
928                                        int index3);
929 void ecp_nistz256_avx2_transpose_convert(void *RESULTx4, const void *in);
930 void ecp_nistz256_avx2_convert_transpose_back(void *result, const void *Ax4);
931 void ecp_nistz256_avx2_point_add_affine_x4(void *RESULTx4, const void *Ax4,
932                                            const void *Bx4);
933 void ecp_nistz256_avx2_point_add_affines_x4(void *RESULTx4, const void *Ax4,
934                                             const void *Bx4);
935 void ecp_nistz256_avx2_to_mont(void *RESULTx4, const void *Ax4);
936 void ecp_nistz256_avx2_from_mont(void *RESULTx4, const void *Ax4);
937 void ecp_nistz256_avx2_set1(void *RESULTx4);
938 int ecp_nistz_avx2_eligible(void);
939
940 static void booth_recode_w7(unsigned char *sign,
941                             unsigned char *digit, unsigned char in)
942 {
943     unsigned char s, d;
944
945     s = ~((in >> 7) - 1);
946     d = (1 << 8) - in - 1;
947     d = (d & s) | (in & ~s);
948     d = (d >> 1) + (d & 1);
949
950     *sign = s & 1;
951     *digit = d;
952 }
953
954 /*
955  * ecp_nistz256_avx2_mul_g performs multiplication by G, using only the
956  * precomputed table. It does 4 affine point additions in parallel,
957  * significantly speeding up point multiplication for a fixed value.
958  */
959 static void ecp_nistz256_avx2_mul_g(P256_POINT *r,
960                                     unsigned char p_str[33],
961                                     const P256_POINT_AFFINE(*preComputedTable)[64])
962 {
963     const unsigned int window_size = 7;
964     const unsigned int mask = (1 << (window_size + 1)) - 1;
965     unsigned int wvalue;
966     /* Using 4 windows at a time */
967     unsigned char sign0, digit0;
968     unsigned char sign1, digit1;
969     unsigned char sign2, digit2;
970     unsigned char sign3, digit3;
971     unsigned int idx = 0;
972     BN_ULONG tmp[P256_LIMBS];
973     int i;
974
975     ALIGN32 BN_ULONG aX4[4 * 9 * 3] = { 0 };
976     ALIGN32 BN_ULONG bX4[4 * 9 * 2] = { 0 };
977     ALIGN32 P256_POINT_AFFINE point_arr[4];
978     ALIGN32 P256_POINT res_point_arr[4];
979
980     /* Initial four windows */
981     wvalue = *((u16 *) & p_str[0]);
982     wvalue = (wvalue << 1) & mask;
983     idx += window_size;
984     booth_recode_w7(&sign0, &digit0, wvalue);
985     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
986     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
987     idx += window_size;
988     booth_recode_w7(&sign1, &digit1, wvalue);
989     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
990     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
991     idx += window_size;
992     booth_recode_w7(&sign2, &digit2, wvalue);
993     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
994     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
995     idx += window_size;
996     booth_recode_w7(&sign3, &digit3, wvalue);
997
998     ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[0],
999                                       digit0, digit1, digit2, digit3);
1000
1001     ecp_nistz256_neg(tmp, point_arr[0].Y);
1002     copy_conditional(point_arr[0].Y, tmp, sign0);
1003     ecp_nistz256_neg(tmp, point_arr[1].Y);
1004     copy_conditional(point_arr[1].Y, tmp, sign1);
1005     ecp_nistz256_neg(tmp, point_arr[2].Y);
1006     copy_conditional(point_arr[2].Y, tmp, sign2);
1007     ecp_nistz256_neg(tmp, point_arr[3].Y);
1008     copy_conditional(point_arr[3].Y, tmp, sign3);
1009
1010     ecp_nistz256_avx2_transpose_convert(aX4, point_arr);
1011     ecp_nistz256_avx2_to_mont(aX4, aX4);
1012     ecp_nistz256_avx2_to_mont(&aX4[4 * 9], &aX4[4 * 9]);
1013     ecp_nistz256_avx2_set1(&aX4[4 * 9 * 2]);
1014
1015     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1016     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1017     idx += window_size;
1018     booth_recode_w7(&sign0, &digit0, wvalue);
1019     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1020     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1021     idx += window_size;
1022     booth_recode_w7(&sign1, &digit1, wvalue);
1023     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1024     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1025     idx += window_size;
1026     booth_recode_w7(&sign2, &digit2, wvalue);
1027     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1028     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1029     idx += window_size;
1030     booth_recode_w7(&sign3, &digit3, wvalue);
1031
1032     ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[4 * 1],
1033                                       digit0, digit1, digit2, digit3);
1034
1035     ecp_nistz256_neg(tmp, point_arr[0].Y);
1036     copy_conditional(point_arr[0].Y, tmp, sign0);
1037     ecp_nistz256_neg(tmp, point_arr[1].Y);
1038     copy_conditional(point_arr[1].Y, tmp, sign1);
1039     ecp_nistz256_neg(tmp, point_arr[2].Y);
1040     copy_conditional(point_arr[2].Y, tmp, sign2);
1041     ecp_nistz256_neg(tmp, point_arr[3].Y);
1042     copy_conditional(point_arr[3].Y, tmp, sign3);
1043
1044     ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
1045     ecp_nistz256_avx2_to_mont(bX4, bX4);
1046     ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
1047     /* Optimized when both inputs are affine */
1048     ecp_nistz256_avx2_point_add_affines_x4(aX4, aX4, bX4);
1049
1050     for (i = 2; i < 9; i++) {
1051         wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1052         wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1053         idx += window_size;
1054         booth_recode_w7(&sign0, &digit0, wvalue);
1055         wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1056         wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1057         idx += window_size;
1058         booth_recode_w7(&sign1, &digit1, wvalue);
1059         wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1060         wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1061         idx += window_size;
1062         booth_recode_w7(&sign2, &digit2, wvalue);
1063         wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1064         wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1065         idx += window_size;
1066         booth_recode_w7(&sign3, &digit3, wvalue);
1067
1068         ecp_nistz256_avx2_multi_gather_w7(point_arr,
1069                                           preComputedTable[4 * i],
1070                                           digit0, digit1, digit2, digit3);
1071
1072         ecp_nistz256_neg(tmp, point_arr[0].Y);
1073         copy_conditional(point_arr[0].Y, tmp, sign0);
1074         ecp_nistz256_neg(tmp, point_arr[1].Y);
1075         copy_conditional(point_arr[1].Y, tmp, sign1);
1076         ecp_nistz256_neg(tmp, point_arr[2].Y);
1077         copy_conditional(point_arr[2].Y, tmp, sign2);
1078         ecp_nistz256_neg(tmp, point_arr[3].Y);
1079         copy_conditional(point_arr[3].Y, tmp, sign3);
1080
1081         ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
1082         ecp_nistz256_avx2_to_mont(bX4, bX4);
1083         ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
1084
1085         ecp_nistz256_avx2_point_add_affine_x4(aX4, aX4, bX4);
1086     }
1087
1088     ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 0], &aX4[4 * 9 * 0]);
1089     ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 1], &aX4[4 * 9 * 1]);
1090     ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 2], &aX4[4 * 9 * 2]);
1091
1092     ecp_nistz256_avx2_convert_transpose_back(res_point_arr, aX4);
1093     /* Last window is performed serially */
1094     wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
1095     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1096     booth_recode_w7(&sign0, &digit0, wvalue);
1097     ecp_nistz256_gather_w7((P256_POINT_AFFINE *)r,
1098                            preComputedTable[36], digit0);
1099     ecp_nistz256_neg(tmp, r->Y);
1100     copy_conditional(r->Y, tmp, sign0);
1101     memcpy(r->Z, ONE, sizeof(ONE));
1102     /* Sum the four windows */
1103     ecp_nistz256_point_add(r, r, &res_point_arr[0]);
1104     ecp_nistz256_point_add(r, r, &res_point_arr[1]);
1105     ecp_nistz256_point_add(r, r, &res_point_arr[2]);
1106     ecp_nistz256_point_add(r, r, &res_point_arr[3]);
1107 }
1108 # endif
1109 #endif
1110
1111 __owur static int ecp_nistz256_set_from_affine(EC_POINT *out, const EC_GROUP *group,
1112                                                const P256_POINT_AFFINE *in,
1113                                                BN_CTX *ctx)
1114 {
1115     BIGNUM *x, *y;
1116     BN_ULONG d_x[P256_LIMBS], d_y[P256_LIMBS];
1117     int ret = 0;
1118
1119     x = BN_new();
1120     if (x == NULL)
1121         return 0;
1122     y = BN_new();
1123     if (y == NULL) {
1124         BN_free(x);
1125         return 0;
1126     }
1127     memcpy(d_x, in->X, sizeof(d_x));
1128     bn_set_static_words(x, d_x, P256_LIMBS);
1129
1130     memcpy(d_y, in->Y, sizeof(d_y));
1131     bn_set_static_words(y, d_y, P256_LIMBS);
1132
1133     ret = EC_POINT_set_affine_coordinates_GFp(group, out, x, y, ctx);
1134
1135     BN_free(x);
1136     BN_free(y);
1137
1138     return ret;
1139 }
1140
1141 /* r = scalar*G + sum(scalars[i]*points[i]) */
1142 __owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
1143                                           EC_POINT *r,
1144                                           const BIGNUM *scalar,
1145                                           size_t num,
1146                                           const EC_POINT *points[],
1147                                           const BIGNUM *scalars[], BN_CTX *ctx)
1148 {
1149     int i = 0, ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0;
1150     size_t j;
1151     unsigned char p_str[33] = { 0 };
1152     const PRECOMP256_ROW *preComputedTable = NULL;
1153     const NISTZ256_PRE_COMP *pre_comp = NULL;
1154     const EC_POINT *generator = NULL;
1155     BN_CTX *new_ctx = NULL;
1156     const BIGNUM **new_scalars = NULL;
1157     const EC_POINT **new_points = NULL;
1158     unsigned int idx = 0;
1159     const unsigned int window_size = 7;
1160     const unsigned int mask = (1 << (window_size + 1)) - 1;
1161     unsigned int wvalue;
1162     ALIGN32 union {
1163         P256_POINT p;
1164         P256_POINT_AFFINE a;
1165     } t, p;
1166     BIGNUM *tmp_scalar;
1167
1168     if ((num + 1) == 0 || (num + 1) > OPENSSL_MALLOC_MAX_NELEMS(void *)) {
1169         ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1170         return 0;
1171     }
1172
1173     if (group->meth != r->meth) {
1174         ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
1175         return 0;
1176     }
1177
1178     if ((scalar == NULL) && (num == 0))
1179         return EC_POINT_set_to_infinity(group, r);
1180
1181     for (j = 0; j < num; j++) {
1182         if (group->meth != points[j]->meth) {
1183             ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
1184             return 0;
1185         }
1186     }
1187
1188     if (ctx == NULL) {
1189         ctx = new_ctx = BN_CTX_new();
1190         if (ctx == NULL)
1191             goto err;
1192     }
1193
1194     BN_CTX_start(ctx);
1195
1196     if (scalar) {
1197         generator = EC_GROUP_get0_generator(group);
1198         if (generator == NULL) {
1199             ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_UNDEFINED_GENERATOR);
1200             goto err;
1201         }
1202
1203         /* look if we can use precomputed multiples of generator */
1204         pre_comp = group->pre_comp.nistz256;
1205
1206         if (pre_comp) {
1207             /*
1208              * If there is a precomputed table for the generator, check that
1209              * it was generated with the same generator.
1210              */
1211             EC_POINT *pre_comp_generator = EC_POINT_new(group);
1212             if (pre_comp_generator == NULL)
1213                 goto err;
1214
1215             if (!ecp_nistz256_set_from_affine(pre_comp_generator,
1216                                               group, pre_comp->precomp[0],
1217                                               ctx)) {
1218                 EC_POINT_free(pre_comp_generator);
1219                 goto err;
1220             }
1221
1222             if (0 == EC_POINT_cmp(group, generator, pre_comp_generator, ctx))
1223                 preComputedTable = (const PRECOMP256_ROW *)pre_comp->precomp;
1224
1225             EC_POINT_free(pre_comp_generator);
1226         }
1227
1228         if (preComputedTable == NULL && ecp_nistz256_is_affine_G(generator)) {
1229             /*
1230              * If there is no precomputed data, but the generator is the
1231              * default, a hardcoded table of precomputed data is used. This
1232              * is because applications, such as Apache, do not use
1233              * EC_KEY_precompute_mult.
1234              */
1235             preComputedTable = ecp_nistz256_precomputed;
1236         }
1237
1238         if (preComputedTable) {
1239             if ((BN_num_bits(scalar) > 256)
1240                 || BN_is_negative(scalar)) {
1241                 if ((tmp_scalar = BN_CTX_get(ctx)) == NULL)
1242                     goto err;
1243
1244                 if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
1245                     ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_BN_LIB);
1246                     goto err;
1247                 }
1248                 scalar = tmp_scalar;
1249             }
1250
1251             for (i = 0; i < bn_get_top(scalar) * BN_BYTES; i += BN_BYTES) {
1252                 BN_ULONG d = bn_get_words(scalar)[i / BN_BYTES];
1253
1254                 p_str[i + 0] = (unsigned char)d;
1255                 p_str[i + 1] = (unsigned char)(d >> 8);
1256                 p_str[i + 2] = (unsigned char)(d >> 16);
1257                 p_str[i + 3] = (unsigned char)(d >>= 24);
1258                 if (BN_BYTES == 8) {
1259                     d >>= 8;
1260                     p_str[i + 4] = (unsigned char)d;
1261                     p_str[i + 5] = (unsigned char)(d >> 8);
1262                     p_str[i + 6] = (unsigned char)(d >> 16);
1263                     p_str[i + 7] = (unsigned char)(d >> 24);
1264                 }
1265             }
1266
1267             for (; i < 33; i++)
1268                 p_str[i] = 0;
1269
1270 #if defined(ECP_NISTZ256_AVX2)
1271             if (ecp_nistz_avx2_eligible()) {
1272                 ecp_nistz256_avx2_mul_g(&p.p, p_str, preComputedTable);
1273             } else
1274 #endif
1275             {
1276                 /* First window */
1277                 wvalue = (p_str[0] << 1) & mask;
1278                 idx += window_size;
1279
1280                 wvalue = _booth_recode_w7(wvalue);
1281
1282                 ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
1283                                        wvalue >> 1);
1284
1285                 ecp_nistz256_neg(p.p.Z, p.p.Y);
1286                 copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
1287
1288                 memcpy(p.p.Z, ONE, sizeof(ONE));
1289
1290                 for (i = 1; i < 37; i++) {
1291                     unsigned int off = (idx - 1) / 8;
1292                     wvalue = p_str[off] | p_str[off + 1] << 8;
1293                     wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
1294                     idx += window_size;
1295
1296                     wvalue = _booth_recode_w7(wvalue);
1297
1298                     ecp_nistz256_gather_w7(&t.a,
1299                                            preComputedTable[i], wvalue >> 1);
1300
1301                     ecp_nistz256_neg(t.p.Z, t.a.Y);
1302                     copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
1303
1304                     ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
1305                 }
1306             }
1307         } else {
1308             p_is_infinity = 1;
1309             no_precomp_for_generator = 1;
1310         }
1311     } else
1312         p_is_infinity = 1;
1313
1314     if (no_precomp_for_generator) {
1315         /*
1316          * Without a precomputed table for the generator, it has to be
1317          * handled like a normal point.
1318          */
1319         new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *));
1320         if (new_scalars == NULL) {
1321             ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1322             goto err;
1323         }
1324
1325         new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *));
1326         if (new_points == NULL) {
1327             ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
1328             goto err;
1329         }
1330
1331         memcpy(new_scalars, scalars, num * sizeof(BIGNUM *));
1332         new_scalars[num] = scalar;
1333         memcpy(new_points, points, num * sizeof(EC_POINT *));
1334         new_points[num] = generator;
1335
1336         scalars = new_scalars;
1337         points = new_points;
1338         num++;
1339     }
1340
1341     if (num) {
1342         P256_POINT *out = &t.p;
1343         if (p_is_infinity)
1344             out = &p.p;
1345
1346         if (!ecp_nistz256_windowed_mul(group, out, scalars, points, num, ctx))
1347             goto err;
1348
1349         if (!p_is_infinity)
1350             ecp_nistz256_point_add(&p.p, &p.p, out);
1351     }
1352
1353     /* Not constant-time, but we're only operating on the public output. */
1354     if (!bn_set_words(r->X, p.p.X, P256_LIMBS) ||
1355         !bn_set_words(r->Y, p.p.Y, P256_LIMBS) ||
1356         !bn_set_words(r->Z, p.p.Z, P256_LIMBS)) {
1357         goto err;
1358     }
1359     r->Z_is_one = is_one(r->Z) & 1;
1360
1361     ret = 1;
1362
1363 err:
1364     if (ctx)
1365         BN_CTX_end(ctx);
1366     BN_CTX_free(new_ctx);
1367     OPENSSL_free(new_points);
1368     OPENSSL_free(new_scalars);
1369     return ret;
1370 }
1371
1372 __owur static int ecp_nistz256_get_affine(const EC_GROUP *group,
1373                                           const EC_POINT *point,
1374                                           BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
1375 {
1376     BN_ULONG z_inv2[P256_LIMBS];
1377     BN_ULONG z_inv3[P256_LIMBS];
1378     BN_ULONG x_aff[P256_LIMBS];
1379     BN_ULONG y_aff[P256_LIMBS];
1380     BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS];
1381     BN_ULONG x_ret[P256_LIMBS], y_ret[P256_LIMBS];
1382
1383     if (EC_POINT_is_at_infinity(group, point)) {
1384         ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_POINT_AT_INFINITY);
1385         return 0;
1386     }
1387
1388     if (!ecp_nistz256_bignum_to_field_elem(point_x, point->X) ||
1389         !ecp_nistz256_bignum_to_field_elem(point_y, point->Y) ||
1390         !ecp_nistz256_bignum_to_field_elem(point_z, point->Z)) {
1391         ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_COORDINATES_OUT_OF_RANGE);
1392         return 0;
1393     }
1394
1395     ecp_nistz256_mod_inverse(z_inv3, point_z);
1396     ecp_nistz256_sqr_mont(z_inv2, z_inv3);
1397     ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
1398
1399     if (x != NULL) {
1400         ecp_nistz256_from_mont(x_ret, x_aff);
1401         if (!bn_set_words(x, x_ret, P256_LIMBS))
1402             return 0;
1403     }
1404
1405     if (y != NULL) {
1406         ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
1407         ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
1408         ecp_nistz256_from_mont(y_ret, y_aff);
1409         if (!bn_set_words(y, y_ret, P256_LIMBS))
1410             return 0;
1411     }
1412
1413     return 1;
1414 }
1415
1416 static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group)
1417 {
1418     NISTZ256_PRE_COMP *ret = NULL;
1419
1420     if (!group)
1421         return NULL;
1422
1423     ret = OPENSSL_zalloc(sizeof(*ret));
1424
1425     if (ret == NULL) {
1426         ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1427         return ret;
1428     }
1429
1430     ret->group = group;
1431     ret->w = 6;                 /* default */
1432     ret->references = 1;
1433
1434     ret->lock = CRYPTO_THREAD_lock_new();
1435     if (ret->lock == NULL) {
1436         ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
1437         OPENSSL_free(ret);
1438         return NULL;
1439     }
1440     return ret;
1441 }
1442
1443 NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *p)
1444 {
1445     int i;
1446     if (p != NULL)
1447         CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
1448     return p;
1449 }
1450
1451 void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *pre)
1452 {
1453     int i;
1454
1455     if (pre == NULL)
1456         return;
1457
1458     CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
1459     REF_PRINT_COUNT("EC_nistz256", x);
1460     if (i > 0)
1461         return;
1462     REF_ASSERT_ISNT(i < 0);
1463
1464     OPENSSL_free(pre->precomp_storage);
1465     CRYPTO_THREAD_lock_free(pre->lock);
1466     OPENSSL_free(pre);
1467 }
1468
1469
1470 static int ecp_nistz256_window_have_precompute_mult(const EC_GROUP *group)
1471 {
1472     /* There is a hard-coded table for the default generator. */
1473     const EC_POINT *generator = EC_GROUP_get0_generator(group);
1474
1475     if (generator != NULL && ecp_nistz256_is_affine_G(generator)) {
1476         /* There is a hard-coded table for the default generator. */
1477         return 1;
1478     }
1479
1480     return HAVEPRECOMP(group, nistz256);
1481 }
1482
1483 const EC_METHOD *EC_GFp_nistz256_method(void)
1484 {
1485     static const EC_METHOD ret = {
1486         EC_FLAGS_DEFAULT_OCT,
1487         NID_X9_62_prime_field,
1488         ec_GFp_mont_group_init,
1489         ec_GFp_mont_group_finish,
1490         ec_GFp_mont_group_clear_finish,
1491         ec_GFp_mont_group_copy,
1492         ec_GFp_mont_group_set_curve,
1493         ec_GFp_simple_group_get_curve,
1494         ec_GFp_simple_group_get_degree,
1495         ec_group_simple_order_bits,
1496         ec_GFp_simple_group_check_discriminant,
1497         ec_GFp_simple_point_init,
1498         ec_GFp_simple_point_finish,
1499         ec_GFp_simple_point_clear_finish,
1500         ec_GFp_simple_point_copy,
1501         ec_GFp_simple_point_set_to_infinity,
1502         ec_GFp_simple_set_Jprojective_coordinates_GFp,
1503         ec_GFp_simple_get_Jprojective_coordinates_GFp,
1504         ec_GFp_simple_point_set_affine_coordinates,
1505         ecp_nistz256_get_affine,
1506         0, 0, 0,
1507         ec_GFp_simple_add,
1508         ec_GFp_simple_dbl,
1509         ec_GFp_simple_invert,
1510         ec_GFp_simple_is_at_infinity,
1511         ec_GFp_simple_is_on_curve,
1512         ec_GFp_simple_cmp,
1513         ec_GFp_simple_make_affine,
1514         ec_GFp_simple_points_make_affine,
1515         ecp_nistz256_points_mul,                    /* mul */
1516         ecp_nistz256_mult_precompute,               /* precompute_mult */
1517         ecp_nistz256_window_have_precompute_mult,   /* have_precompute_mult */
1518         ec_GFp_mont_field_mul,
1519         ec_GFp_mont_field_sqr,
1520         0,                                          /* field_div */
1521         ec_GFp_mont_field_encode,
1522         ec_GFp_mont_field_decode,
1523         ec_GFp_mont_field_set_to_one,
1524         ec_key_simple_priv2oct,
1525         ec_key_simple_oct2priv,
1526         0, /* set private */
1527         ec_key_simple_generate_key,
1528         ec_key_simple_check_key,
1529         ec_key_simple_generate_public_key,
1530         0, /* keycopy */
1531         0, /* keyfinish */
1532         ecdh_simple_compute_key
1533     };
1534
1535     return &ret;
1536 }