Remove /* foo.c */ comments
[openssl.git] / crypto / bn / bn_gf2m.c
1 /* ====================================================================
2  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
3  *
4  * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
5  * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
6  * to the OpenSSL project.
7  *
8  * The ECC Code is licensed pursuant to the OpenSSL open source
9  * license provided below.
10  *
11  * In addition, Sun covenants to all licensees who provide a reciprocal
12  * covenant with respect to their own patents if any, not to sue under
13  * current and future patent claims necessarily infringed by the making,
14  * using, practicing, selling, offering for sale and/or otherwise
15  * disposing of the ECC Code as delivered hereunder (or portions thereof),
16  * provided that such covenant shall not apply:
17  *  1) for code that a licensee deletes from the ECC Code;
18  *  2) separates from the ECC Code; or
19  *  3) for infringements caused by:
20  *       i) the modification of the ECC Code or
21  *      ii) the combination of the ECC Code with other software or
22  *          devices where such combination causes the infringement.
23  *
24  * The software is originally written by Sheueling Chang Shantz and
25  * Douglas Stebila of Sun Microsystems Laboratories.
26  *
27  */
28
29 /*
30  * NOTE: This file is licensed pursuant to the OpenSSL license below and may
31  * be modified; but after modifications, the above covenant may no longer
32  * apply! In such cases, the corresponding paragraph ["In addition, Sun
33  * covenants ... causes the infringement."] and this note can be edited out;
34  * but please keep the Sun copyright notice and attribution.
35  */
36
37 /* ====================================================================
38  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  *
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  *
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in
49  *    the documentation and/or other materials provided with the
50  *    distribution.
51  *
52  * 3. All advertising materials mentioning features or use of this
53  *    software must display the following acknowledgment:
54  *    "This product includes software developed by the OpenSSL Project
55  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
56  *
57  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
58  *    endorse or promote products derived from this software without
59  *    prior written permission. For written permission, please contact
60  *    openssl-core@openssl.org.
61  *
62  * 5. Products derived from this software may not be called "OpenSSL"
63  *    nor may "OpenSSL" appear in their names without prior written
64  *    permission of the OpenSSL Project.
65  *
66  * 6. Redistributions of any form whatsoever must retain the following
67  *    acknowledgment:
68  *    "This product includes software developed by the OpenSSL Project
69  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
70  *
71  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
72  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
73  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
74  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
75  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
76  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
77  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
79  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
80  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
81  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
82  * OF THE POSSIBILITY OF SUCH DAMAGE.
83  * ====================================================================
84  *
85  * This product includes cryptographic software written by Eric Young
86  * (eay@cryptsoft.com).  This product includes software written by Tim
87  * Hudson (tjh@cryptsoft.com).
88  *
89  */
90
91 #include <assert.h>
92 #include <limits.h>
93 #include <stdio.h>
94 #include "internal/cryptlib.h"
95 #include "bn_lcl.h"
96
97 #ifndef OPENSSL_NO_EC2M
98
99 /*
100  * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should
101  * fail.
102  */
103 # define MAX_ITERATIONS 50
104
105 static const BN_ULONG SQR_tb[16] = { 0, 1, 4, 5, 16, 17, 20, 21,
106     64, 65, 68, 69, 80, 81, 84, 85
107 };
108
109 /* Platform-specific macros to accelerate squaring. */
110 # if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
111 #  define SQR1(w) \
112     SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
113     SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
114     SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
115     SQR_tb[(w) >> 36 & 0xF] <<  8 | SQR_tb[(w) >> 32 & 0xF]
116 #  define SQR0(w) \
117     SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
118     SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
119     SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
120     SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
121 # endif
122 # ifdef THIRTY_TWO_BIT
123 #  define SQR1(w) \
124     SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
125     SQR_tb[(w) >> 20 & 0xF] <<  8 | SQR_tb[(w) >> 16 & 0xF]
126 #  define SQR0(w) \
127     SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
128     SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
129 # endif
130
131 # if !defined(OPENSSL_BN_ASM_GF2m)
132 /*
133  * Product of two polynomials a, b each with degree < BN_BITS2 - 1, result is
134  * a polynomial r with degree < 2 * BN_BITS - 1 The caller MUST ensure that
135  * the variables have the right amount of space allocated.
136  */
137 #  ifdef THIRTY_TWO_BIT
138 static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a,
139                             const BN_ULONG b)
140 {
141     register BN_ULONG h, l, s;
142     BN_ULONG tab[8], top2b = a >> 30;
143     register BN_ULONG a1, a2, a4;
144
145     a1 = a & (0x3FFFFFFF);
146     a2 = a1 << 1;
147     a4 = a2 << 1;
148
149     tab[0] = 0;
150     tab[1] = a1;
151     tab[2] = a2;
152     tab[3] = a1 ^ a2;
153     tab[4] = a4;
154     tab[5] = a1 ^ a4;
155     tab[6] = a2 ^ a4;
156     tab[7] = a1 ^ a2 ^ a4;
157
158     s = tab[b & 0x7];
159     l = s;
160     s = tab[b >> 3 & 0x7];
161     l ^= s << 3;
162     h = s >> 29;
163     s = tab[b >> 6 & 0x7];
164     l ^= s << 6;
165     h ^= s >> 26;
166     s = tab[b >> 9 & 0x7];
167     l ^= s << 9;
168     h ^= s >> 23;
169     s = tab[b >> 12 & 0x7];
170     l ^= s << 12;
171     h ^= s >> 20;
172     s = tab[b >> 15 & 0x7];
173     l ^= s << 15;
174     h ^= s >> 17;
175     s = tab[b >> 18 & 0x7];
176     l ^= s << 18;
177     h ^= s >> 14;
178     s = tab[b >> 21 & 0x7];
179     l ^= s << 21;
180     h ^= s >> 11;
181     s = tab[b >> 24 & 0x7];
182     l ^= s << 24;
183     h ^= s >> 8;
184     s = tab[b >> 27 & 0x7];
185     l ^= s << 27;
186     h ^= s >> 5;
187     s = tab[b >> 30];
188     l ^= s << 30;
189     h ^= s >> 2;
190
191     /* compensate for the top two bits of a */
192
193     if (top2b & 01) {
194         l ^= b << 30;
195         h ^= b >> 2;
196     }
197     if (top2b & 02) {
198         l ^= b << 31;
199         h ^= b >> 1;
200     }
201
202     *r1 = h;
203     *r0 = l;
204 }
205 #  endif
206 #  if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
207 static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a,
208                             const BN_ULONG b)
209 {
210     register BN_ULONG h, l, s;
211     BN_ULONG tab[16], top3b = a >> 61;
212     register BN_ULONG a1, a2, a4, a8;
213
214     a1 = a & (0x1FFFFFFFFFFFFFFFULL);
215     a2 = a1 << 1;
216     a4 = a2 << 1;
217     a8 = a4 << 1;
218
219     tab[0] = 0;
220     tab[1] = a1;
221     tab[2] = a2;
222     tab[3] = a1 ^ a2;
223     tab[4] = a4;
224     tab[5] = a1 ^ a4;
225     tab[6] = a2 ^ a4;
226     tab[7] = a1 ^ a2 ^ a4;
227     tab[8] = a8;
228     tab[9] = a1 ^ a8;
229     tab[10] = a2 ^ a8;
230     tab[11] = a1 ^ a2 ^ a8;
231     tab[12] = a4 ^ a8;
232     tab[13] = a1 ^ a4 ^ a8;
233     tab[14] = a2 ^ a4 ^ a8;
234     tab[15] = a1 ^ a2 ^ a4 ^ a8;
235
236     s = tab[b & 0xF];
237     l = s;
238     s = tab[b >> 4 & 0xF];
239     l ^= s << 4;
240     h = s >> 60;
241     s = tab[b >> 8 & 0xF];
242     l ^= s << 8;
243     h ^= s >> 56;
244     s = tab[b >> 12 & 0xF];
245     l ^= s << 12;
246     h ^= s >> 52;
247     s = tab[b >> 16 & 0xF];
248     l ^= s << 16;
249     h ^= s >> 48;
250     s = tab[b >> 20 & 0xF];
251     l ^= s << 20;
252     h ^= s >> 44;
253     s = tab[b >> 24 & 0xF];
254     l ^= s << 24;
255     h ^= s >> 40;
256     s = tab[b >> 28 & 0xF];
257     l ^= s << 28;
258     h ^= s >> 36;
259     s = tab[b >> 32 & 0xF];
260     l ^= s << 32;
261     h ^= s >> 32;
262     s = tab[b >> 36 & 0xF];
263     l ^= s << 36;
264     h ^= s >> 28;
265     s = tab[b >> 40 & 0xF];
266     l ^= s << 40;
267     h ^= s >> 24;
268     s = tab[b >> 44 & 0xF];
269     l ^= s << 44;
270     h ^= s >> 20;
271     s = tab[b >> 48 & 0xF];
272     l ^= s << 48;
273     h ^= s >> 16;
274     s = tab[b >> 52 & 0xF];
275     l ^= s << 52;
276     h ^= s >> 12;
277     s = tab[b >> 56 & 0xF];
278     l ^= s << 56;
279     h ^= s >> 8;
280     s = tab[b >> 60];
281     l ^= s << 60;
282     h ^= s >> 4;
283
284     /* compensate for the top three bits of a */
285
286     if (top3b & 01) {
287         l ^= b << 61;
288         h ^= b >> 3;
289     }
290     if (top3b & 02) {
291         l ^= b << 62;
292         h ^= b >> 2;
293     }
294     if (top3b & 04) {
295         l ^= b << 63;
296         h ^= b >> 1;
297     }
298
299     *r1 = h;
300     *r0 = l;
301 }
302 #  endif
303
304 /*
305  * Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
306  * result is a polynomial r with degree < 4 * BN_BITS2 - 1 The caller MUST
307  * ensure that the variables have the right amount of space allocated.
308  */
309 static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0,
310                             const BN_ULONG b1, const BN_ULONG b0)
311 {
312     BN_ULONG m1, m0;
313     /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
314     bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1);
315     bn_GF2m_mul_1x1(r + 1, r, a0, b0);
316     bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
317     /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
318     r[2] ^= m1 ^ r[1] ^ r[3];   /* h0 ^= m1 ^ l1 ^ h1; */
319     r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
320 }
321 # else
322 void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1,
323                      BN_ULONG b0);
324 # endif
325
326 /*
327  * Add polynomials a and b and store result in r; r could be a or b, a and b
328  * could be equal; r is the bitwise XOR of a and b.
329  */
330 int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
331 {
332     int i;
333     const BIGNUM *at, *bt;
334
335     bn_check_top(a);
336     bn_check_top(b);
337
338     if (a->top < b->top) {
339         at = b;
340         bt = a;
341     } else {
342         at = a;
343         bt = b;
344     }
345
346     if (bn_wexpand(r, at->top) == NULL)
347         return 0;
348
349     for (i = 0; i < bt->top; i++) {
350         r->d[i] = at->d[i] ^ bt->d[i];
351     }
352     for (; i < at->top; i++) {
353         r->d[i] = at->d[i];
354     }
355
356     r->top = at->top;
357     bn_correct_top(r);
358
359     return 1;
360 }
361
362 /*-
363  * Some functions allow for representation of the irreducible polynomials
364  * as an int[], say p.  The irreducible f(t) is then of the form:
365  *     t^p[0] + t^p[1] + ... + t^p[k]
366  * where m = p[0] > p[1] > ... > p[k] = 0.
367  */
368
369 /* Performs modular reduction of a and store result in r.  r could be a. */
370 int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
371 {
372     int j, k;
373     int n, dN, d0, d1;
374     BN_ULONG zz, *z;
375
376     bn_check_top(a);
377
378     if (!p[0]) {
379         /* reduction mod 1 => return 0 */
380         BN_zero(r);
381         return 1;
382     }
383
384     /*
385      * Since the algorithm does reduction in the r value, if a != r, copy the
386      * contents of a into r so we can do reduction in r.
387      */
388     if (a != r) {
389         if (!bn_wexpand(r, a->top))
390             return 0;
391         for (j = 0; j < a->top; j++) {
392             r->d[j] = a->d[j];
393         }
394         r->top = a->top;
395     }
396     z = r->d;
397
398     /* start reduction */
399     dN = p[0] / BN_BITS2;
400     for (j = r->top - 1; j > dN;) {
401         zz = z[j];
402         if (z[j] == 0) {
403             j--;
404             continue;
405         }
406         z[j] = 0;
407
408         for (k = 1; p[k] != 0; k++) {
409             /* reducing component t^p[k] */
410             n = p[0] - p[k];
411             d0 = n % BN_BITS2;
412             d1 = BN_BITS2 - d0;
413             n /= BN_BITS2;
414             z[j - n] ^= (zz >> d0);
415             if (d0)
416                 z[j - n - 1] ^= (zz << d1);
417         }
418
419         /* reducing component t^0 */
420         n = dN;
421         d0 = p[0] % BN_BITS2;
422         d1 = BN_BITS2 - d0;
423         z[j - n] ^= (zz >> d0);
424         if (d0)
425             z[j - n - 1] ^= (zz << d1);
426     }
427
428     /* final round of reduction */
429     while (j == dN) {
430
431         d0 = p[0] % BN_BITS2;
432         zz = z[dN] >> d0;
433         if (zz == 0)
434             break;
435         d1 = BN_BITS2 - d0;
436
437         /* clear up the top d1 bits */
438         if (d0)
439             z[dN] = (z[dN] << d1) >> d1;
440         else
441             z[dN] = 0;
442         z[0] ^= zz;             /* reduction t^0 component */
443
444         for (k = 1; p[k] != 0; k++) {
445             BN_ULONG tmp_ulong;
446
447             /* reducing component t^p[k] */
448             n = p[k] / BN_BITS2;
449             d0 = p[k] % BN_BITS2;
450             d1 = BN_BITS2 - d0;
451             z[n] ^= (zz << d0);
452             if (d0 && (tmp_ulong = zz >> d1))
453                 z[n + 1] ^= tmp_ulong;
454         }
455
456     }
457
458     bn_correct_top(r);
459     return 1;
460 }
461
462 /*
463  * Performs modular reduction of a by p and store result in r.  r could be a.
464  * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
465  * function is only provided for convenience; for best performance, use the
466  * BN_GF2m_mod_arr function.
467  */
468 int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
469 {
470     int ret = 0;
471     int arr[6];
472     bn_check_top(a);
473     bn_check_top(p);
474     ret = BN_GF2m_poly2arr(p, arr, OSSL_NELEM(arr));
475     if (!ret || ret > (int)OSSL_NELEM(arr)) {
476         BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH);
477         return 0;
478     }
479     ret = BN_GF2m_mod_arr(r, a, arr);
480     bn_check_top(r);
481     return ret;
482 }
483
484 /*
485  * Compute the product of two polynomials a and b, reduce modulo p, and store
486  * the result in r.  r could be a or b; a could be b.
487  */
488 int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
489                         const int p[], BN_CTX *ctx)
490 {
491     int zlen, i, j, k, ret = 0;
492     BIGNUM *s;
493     BN_ULONG x1, x0, y1, y0, zz[4];
494
495     bn_check_top(a);
496     bn_check_top(b);
497
498     if (a == b) {
499         return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
500     }
501
502     BN_CTX_start(ctx);
503     if ((s = BN_CTX_get(ctx)) == NULL)
504         goto err;
505
506     zlen = a->top + b->top + 4;
507     if (!bn_wexpand(s, zlen))
508         goto err;
509     s->top = zlen;
510
511     for (i = 0; i < zlen; i++)
512         s->d[i] = 0;
513
514     for (j = 0; j < b->top; j += 2) {
515         y0 = b->d[j];
516         y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1];
517         for (i = 0; i < a->top; i += 2) {
518             x0 = a->d[i];
519             x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1];
520             bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
521             for (k = 0; k < 4; k++)
522                 s->d[i + j + k] ^= zz[k];
523         }
524     }
525
526     bn_correct_top(s);
527     if (BN_GF2m_mod_arr(r, s, p))
528         ret = 1;
529     bn_check_top(r);
530
531  err:
532     BN_CTX_end(ctx);
533     return ret;
534 }
535
536 /*
537  * Compute the product of two polynomials a and b, reduce modulo p, and store
538  * the result in r.  r could be a or b; a could equal b. This function calls
539  * down to the BN_GF2m_mod_mul_arr implementation; this wrapper function is
540  * only provided for convenience; for best performance, use the
541  * BN_GF2m_mod_mul_arr function.
542  */
543 int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
544                     const BIGNUM *p, BN_CTX *ctx)
545 {
546     int ret = 0;
547     const int max = BN_num_bits(p) + 1;
548     int *arr = NULL;
549     bn_check_top(a);
550     bn_check_top(b);
551     bn_check_top(p);
552     if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
553         goto err;
554     ret = BN_GF2m_poly2arr(p, arr, max);
555     if (!ret || ret > max) {
556         BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH);
557         goto err;
558     }
559     ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
560     bn_check_top(r);
561  err:
562     OPENSSL_free(arr);
563     return ret;
564 }
565
566 /* Square a, reduce the result mod p, and store it in a.  r could be a. */
567 int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
568                         BN_CTX *ctx)
569 {
570     int i, ret = 0;
571     BIGNUM *s;
572
573     bn_check_top(a);
574     BN_CTX_start(ctx);
575     if ((s = BN_CTX_get(ctx)) == NULL)
576         goto err;
577     if (!bn_wexpand(s, 2 * a->top))
578         goto err;
579
580     for (i = a->top - 1; i >= 0; i--) {
581         s->d[2 * i + 1] = SQR1(a->d[i]);
582         s->d[2 * i] = SQR0(a->d[i]);
583     }
584
585     s->top = 2 * a->top;
586     bn_correct_top(s);
587     if (!BN_GF2m_mod_arr(r, s, p))
588         goto err;
589     bn_check_top(r);
590     ret = 1;
591  err:
592     BN_CTX_end(ctx);
593     return ret;
594 }
595
596 /*
597  * Square a, reduce the result mod p, and store it in a.  r could be a. This
598  * function calls down to the BN_GF2m_mod_sqr_arr implementation; this
599  * wrapper function is only provided for convenience; for best performance,
600  * use the BN_GF2m_mod_sqr_arr function.
601  */
602 int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
603 {
604     int ret = 0;
605     const int max = BN_num_bits(p) + 1;
606     int *arr = NULL;
607
608     bn_check_top(a);
609     bn_check_top(p);
610     if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
611         goto err;
612     ret = BN_GF2m_poly2arr(p, arr, max);
613     if (!ret || ret > max) {
614         BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH);
615         goto err;
616     }
617     ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
618     bn_check_top(r);
619  err:
620     OPENSSL_free(arr);
621     return ret;
622 }
623
624 /*
625  * Invert a, reduce modulo p, and store the result in r. r could be a. Uses
626  * Modified Almost Inverse Algorithm (Algorithm 10) from Hankerson, D.,
627  * Hernandez, J.L., and Menezes, A.  "Software Implementation of Elliptic
628  * Curve Cryptography Over Binary Fields".
629  */
630 int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
631 {
632     BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
633     int ret = 0;
634
635     bn_check_top(a);
636     bn_check_top(p);
637
638     BN_CTX_start(ctx);
639
640     if ((b = BN_CTX_get(ctx)) == NULL)
641         goto err;
642     if ((c = BN_CTX_get(ctx)) == NULL)
643         goto err;
644     if ((u = BN_CTX_get(ctx)) == NULL)
645         goto err;
646     if ((v = BN_CTX_get(ctx)) == NULL)
647         goto err;
648
649     if (!BN_GF2m_mod(u, a, p))
650         goto err;
651     if (BN_is_zero(u))
652         goto err;
653
654     if (!BN_copy(v, p))
655         goto err;
656 # if 0
657     if (!BN_one(b))
658         goto err;
659
660     while (1) {
661         while (!BN_is_odd(u)) {
662             if (BN_is_zero(u))
663                 goto err;
664             if (!BN_rshift1(u, u))
665                 goto err;
666             if (BN_is_odd(b)) {
667                 if (!BN_GF2m_add(b, b, p))
668                     goto err;
669             }
670             if (!BN_rshift1(b, b))
671                 goto err;
672         }
673
674         if (BN_abs_is_word(u, 1))
675             break;
676
677         if (BN_num_bits(u) < BN_num_bits(v)) {
678             tmp = u;
679             u = v;
680             v = tmp;
681             tmp = b;
682             b = c;
683             c = tmp;
684         }
685
686         if (!BN_GF2m_add(u, u, v))
687             goto err;
688         if (!BN_GF2m_add(b, b, c))
689             goto err;
690     }
691 # else
692     {
693         int i;
694         int ubits = BN_num_bits(u);
695         int vbits = BN_num_bits(v); /* v is copy of p */
696         int top = p->top;
697         BN_ULONG *udp, *bdp, *vdp, *cdp;
698
699         if (!bn_wexpand(u, top))
700             goto err;
701         udp = u->d;
702         for (i = u->top; i < top; i++)
703             udp[i] = 0;
704         u->top = top;
705         if (!bn_wexpand(b, top))
706           goto err;
707         bdp = b->d;
708         bdp[0] = 1;
709         for (i = 1; i < top; i++)
710             bdp[i] = 0;
711         b->top = top;
712         if (!bn_wexpand(c, top))
713           goto err;
714         cdp = c->d;
715         for (i = 0; i < top; i++)
716             cdp[i] = 0;
717         c->top = top;
718         vdp = v->d;             /* It pays off to "cache" *->d pointers,
719                                  * because it allows optimizer to be more
720                                  * aggressive. But we don't have to "cache"
721                                  * p->d, because *p is declared 'const'... */
722         while (1) {
723             while (ubits && !(udp[0] & 1)) {
724                 BN_ULONG u0, u1, b0, b1, mask;
725
726                 u0 = udp[0];
727                 b0 = bdp[0];
728                 mask = (BN_ULONG)0 - (b0 & 1);
729                 b0 ^= p->d[0] & mask;
730                 for (i = 0; i < top - 1; i++) {
731                     u1 = udp[i + 1];
732                     udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2;
733                     u0 = u1;
734                     b1 = bdp[i + 1] ^ (p->d[i + 1] & mask);
735                     bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2;
736                     b0 = b1;
737                 }
738                 udp[i] = u0 >> 1;
739                 bdp[i] = b0 >> 1;
740                 ubits--;
741             }
742
743             if (ubits <= BN_BITS2) {
744                 if (udp[0] == 0) /* poly was reducible */
745                     goto err;
746                 if (udp[0] == 1)
747                     break;
748             }
749
750             if (ubits < vbits) {
751                 i = ubits;
752                 ubits = vbits;
753                 vbits = i;
754                 tmp = u;
755                 u = v;
756                 v = tmp;
757                 tmp = b;
758                 b = c;
759                 c = tmp;
760                 udp = vdp;
761                 vdp = v->d;
762                 bdp = cdp;
763                 cdp = c->d;
764             }
765             for (i = 0; i < top; i++) {
766                 udp[i] ^= vdp[i];
767                 bdp[i] ^= cdp[i];
768             }
769             if (ubits == vbits) {
770                 BN_ULONG ul;
771                 int utop = (ubits - 1) / BN_BITS2;
772
773                 while ((ul = udp[utop]) == 0 && utop)
774                     utop--;
775                 ubits = utop * BN_BITS2 + BN_num_bits_word(ul);
776             }
777         }
778         bn_correct_top(b);
779     }
780 # endif
781
782     if (!BN_copy(r, b))
783         goto err;
784     bn_check_top(r);
785     ret = 1;
786
787  err:
788 # ifdef BN_DEBUG                /* BN_CTX_end would complain about the
789                                  * expanded form */
790     bn_correct_top(c);
791     bn_correct_top(u);
792     bn_correct_top(v);
793 # endif
794     BN_CTX_end(ctx);
795     return ret;
796 }
797
798 /*
799  * Invert xx, reduce modulo p, and store the result in r. r could be xx.
800  * This function calls down to the BN_GF2m_mod_inv implementation; this
801  * wrapper function is only provided for convenience; for best performance,
802  * use the BN_GF2m_mod_inv function.
803  */
804 int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[],
805                         BN_CTX *ctx)
806 {
807     BIGNUM *field;
808     int ret = 0;
809
810     bn_check_top(xx);
811     BN_CTX_start(ctx);
812     if ((field = BN_CTX_get(ctx)) == NULL)
813         goto err;
814     if (!BN_GF2m_arr2poly(p, field))
815         goto err;
816
817     ret = BN_GF2m_mod_inv(r, xx, field, ctx);
818     bn_check_top(r);
819
820  err:
821     BN_CTX_end(ctx);
822     return ret;
823 }
824
825 # ifndef OPENSSL_SUN_GF2M_DIV
826 /*
827  * Divide y by x, reduce modulo p, and store the result in r. r could be x
828  * or y, x could equal y.
829  */
830 int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x,
831                     const BIGNUM *p, BN_CTX *ctx)
832 {
833     BIGNUM *xinv = NULL;
834     int ret = 0;
835
836     bn_check_top(y);
837     bn_check_top(x);
838     bn_check_top(p);
839
840     BN_CTX_start(ctx);
841     xinv = BN_CTX_get(ctx);
842     if (xinv == NULL)
843         goto err;
844
845     if (!BN_GF2m_mod_inv(xinv, x, p, ctx))
846         goto err;
847     if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx))
848         goto err;
849     bn_check_top(r);
850     ret = 1;
851
852  err:
853     BN_CTX_end(ctx);
854     return ret;
855 }
856 # else
857 /*
858  * Divide y by x, reduce modulo p, and store the result in r. r could be x
859  * or y, x could equal y. Uses algorithm Modular_Division_GF(2^m) from
860  * Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to the
861  * Great Divide".
862  */
863 int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x,
864                     const BIGNUM *p, BN_CTX *ctx)
865 {
866     BIGNUM *a, *b, *u, *v;
867     int ret = 0;
868
869     bn_check_top(y);
870     bn_check_top(x);
871     bn_check_top(p);
872
873     BN_CTX_start(ctx);
874
875     a = BN_CTX_get(ctx);
876     b = BN_CTX_get(ctx);
877     u = BN_CTX_get(ctx);
878     v = BN_CTX_get(ctx);
879     if (v == NULL)
880         goto err;
881
882     /* reduce x and y mod p */
883     if (!BN_GF2m_mod(u, y, p))
884         goto err;
885     if (!BN_GF2m_mod(a, x, p))
886         goto err;
887     if (!BN_copy(b, p))
888         goto err;
889
890     while (!BN_is_odd(a)) {
891         if (!BN_rshift1(a, a))
892             goto err;
893         if (BN_is_odd(u))
894             if (!BN_GF2m_add(u, u, p))
895                 goto err;
896         if (!BN_rshift1(u, u))
897             goto err;
898     }
899
900     do {
901         if (BN_GF2m_cmp(b, a) > 0) {
902             if (!BN_GF2m_add(b, b, a))
903                 goto err;
904             if (!BN_GF2m_add(v, v, u))
905                 goto err;
906             do {
907                 if (!BN_rshift1(b, b))
908                     goto err;
909                 if (BN_is_odd(v))
910                     if (!BN_GF2m_add(v, v, p))
911                         goto err;
912                 if (!BN_rshift1(v, v))
913                     goto err;
914             } while (!BN_is_odd(b));
915         } else if (BN_abs_is_word(a, 1))
916             break;
917         else {
918             if (!BN_GF2m_add(a, a, b))
919                 goto err;
920             if (!BN_GF2m_add(u, u, v))
921                 goto err;
922             do {
923                 if (!BN_rshift1(a, a))
924                     goto err;
925                 if (BN_is_odd(u))
926                     if (!BN_GF2m_add(u, u, p))
927                         goto err;
928                 if (!BN_rshift1(u, u))
929                     goto err;
930             } while (!BN_is_odd(a));
931         }
932     } while (1);
933
934     if (!BN_copy(r, u))
935         goto err;
936     bn_check_top(r);
937     ret = 1;
938
939  err:
940     BN_CTX_end(ctx);
941     return ret;
942 }
943 # endif
944
945 /*
946  * Divide yy by xx, reduce modulo p, and store the result in r. r could be xx
947  * * or yy, xx could equal yy. This function calls down to the
948  * BN_GF2m_mod_div implementation; this wrapper function is only provided for
949  * convenience; for best performance, use the BN_GF2m_mod_div function.
950  */
951 int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx,
952                         const int p[], BN_CTX *ctx)
953 {
954     BIGNUM *field;
955     int ret = 0;
956
957     bn_check_top(yy);
958     bn_check_top(xx);
959
960     BN_CTX_start(ctx);
961     if ((field = BN_CTX_get(ctx)) == NULL)
962         goto err;
963     if (!BN_GF2m_arr2poly(p, field))
964         goto err;
965
966     ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
967     bn_check_top(r);
968
969  err:
970     BN_CTX_end(ctx);
971     return ret;
972 }
973
974 /*
975  * Compute the bth power of a, reduce modulo p, and store the result in r.  r
976  * could be a. Uses simple square-and-multiply algorithm A.5.1 from IEEE
977  * P1363.
978  */
979 int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
980                         const int p[], BN_CTX *ctx)
981 {
982     int ret = 0, i, n;
983     BIGNUM *u;
984
985     bn_check_top(a);
986     bn_check_top(b);
987
988     if (BN_is_zero(b))
989         return (BN_one(r));
990
991     if (BN_abs_is_word(b, 1))
992         return (BN_copy(r, a) != NULL);
993
994     BN_CTX_start(ctx);
995     if ((u = BN_CTX_get(ctx)) == NULL)
996         goto err;
997
998     if (!BN_GF2m_mod_arr(u, a, p))
999         goto err;
1000
1001     n = BN_num_bits(b) - 1;
1002     for (i = n - 1; i >= 0; i--) {
1003         if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx))
1004             goto err;
1005         if (BN_is_bit_set(b, i)) {
1006             if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx))
1007                 goto err;
1008         }
1009     }
1010     if (!BN_copy(r, u))
1011         goto err;
1012     bn_check_top(r);
1013     ret = 1;
1014  err:
1015     BN_CTX_end(ctx);
1016     return ret;
1017 }
1018
1019 /*
1020  * Compute the bth power of a, reduce modulo p, and store the result in r.  r
1021  * could be a. This function calls down to the BN_GF2m_mod_exp_arr
1022  * implementation; this wrapper function is only provided for convenience;
1023  * for best performance, use the BN_GF2m_mod_exp_arr function.
1024  */
1025 int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
1026                     const BIGNUM *p, BN_CTX *ctx)
1027 {
1028     int ret = 0;
1029     const int max = BN_num_bits(p) + 1;
1030     int *arr = NULL;
1031     bn_check_top(a);
1032     bn_check_top(b);
1033     bn_check_top(p);
1034     if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
1035         goto err;
1036     ret = BN_GF2m_poly2arr(p, arr, max);
1037     if (!ret || ret > max) {
1038         BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH);
1039         goto err;
1040     }
1041     ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
1042     bn_check_top(r);
1043  err:
1044     OPENSSL_free(arr);
1045     return ret;
1046 }
1047
1048 /*
1049  * Compute the square root of a, reduce modulo p, and store the result in r.
1050  * r could be a. Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
1051  */
1052 int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[],
1053                          BN_CTX *ctx)
1054 {
1055     int ret = 0;
1056     BIGNUM *u;
1057
1058     bn_check_top(a);
1059
1060     if (!p[0]) {
1061         /* reduction mod 1 => return 0 */
1062         BN_zero(r);
1063         return 1;
1064     }
1065
1066     BN_CTX_start(ctx);
1067     if ((u = BN_CTX_get(ctx)) == NULL)
1068         goto err;
1069
1070     if (!BN_set_bit(u, p[0] - 1))
1071         goto err;
1072     ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
1073     bn_check_top(r);
1074
1075  err:
1076     BN_CTX_end(ctx);
1077     return ret;
1078 }
1079
1080 /*
1081  * Compute the square root of a, reduce modulo p, and store the result in r.
1082  * r could be a. This function calls down to the BN_GF2m_mod_sqrt_arr
1083  * implementation; this wrapper function is only provided for convenience;
1084  * for best performance, use the BN_GF2m_mod_sqrt_arr function.
1085  */
1086 int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
1087 {
1088     int ret = 0;
1089     const int max = BN_num_bits(p) + 1;
1090     int *arr = NULL;
1091     bn_check_top(a);
1092     bn_check_top(p);
1093     if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
1094         goto err;
1095     ret = BN_GF2m_poly2arr(p, arr, max);
1096     if (!ret || ret > max) {
1097         BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH);
1098         goto err;
1099     }
1100     ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
1101     bn_check_top(r);
1102  err:
1103     OPENSSL_free(arr);
1104     return ret;
1105 }
1106
1107 /*
1108  * Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns
1109  * 0. Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
1110  */
1111 int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[],
1112                                BN_CTX *ctx)
1113 {
1114     int ret = 0, count = 0, j;
1115     BIGNUM *a, *z, *rho, *w, *w2, *tmp;
1116
1117     bn_check_top(a_);
1118
1119     if (!p[0]) {
1120         /* reduction mod 1 => return 0 */
1121         BN_zero(r);
1122         return 1;
1123     }
1124
1125     BN_CTX_start(ctx);
1126     a = BN_CTX_get(ctx);
1127     z = BN_CTX_get(ctx);
1128     w = BN_CTX_get(ctx);
1129     if (w == NULL)
1130         goto err;
1131
1132     if (!BN_GF2m_mod_arr(a, a_, p))
1133         goto err;
1134
1135     if (BN_is_zero(a)) {
1136         BN_zero(r);
1137         ret = 1;
1138         goto err;
1139     }
1140
1141     if (p[0] & 0x1) {           /* m is odd */
1142         /* compute half-trace of a */
1143         if (!BN_copy(z, a))
1144             goto err;
1145         for (j = 1; j <= (p[0] - 1) / 2; j++) {
1146             if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
1147                 goto err;
1148             if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
1149                 goto err;
1150             if (!BN_GF2m_add(z, z, a))
1151                 goto err;
1152         }
1153
1154     } else {                    /* m is even */
1155
1156         rho = BN_CTX_get(ctx);
1157         w2 = BN_CTX_get(ctx);
1158         tmp = BN_CTX_get(ctx);
1159         if (tmp == NULL)
1160             goto err;
1161         do {
1162             if (!BN_rand(rho, p[0], 0, 0))
1163                 goto err;
1164             if (!BN_GF2m_mod_arr(rho, rho, p))
1165                 goto err;
1166             BN_zero(z);
1167             if (!BN_copy(w, rho))
1168                 goto err;
1169             for (j = 1; j <= p[0] - 1; j++) {
1170                 if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
1171                     goto err;
1172                 if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx))
1173                     goto err;
1174                 if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx))
1175                     goto err;
1176                 if (!BN_GF2m_add(z, z, tmp))
1177                     goto err;
1178                 if (!BN_GF2m_add(w, w2, rho))
1179                     goto err;
1180             }
1181             count++;
1182         } while (BN_is_zero(w) && (count < MAX_ITERATIONS));
1183         if (BN_is_zero(w)) {
1184             BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_TOO_MANY_ITERATIONS);
1185             goto err;
1186         }
1187     }
1188
1189     if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx))
1190         goto err;
1191     if (!BN_GF2m_add(w, z, w))
1192         goto err;
1193     if (BN_GF2m_cmp(w, a)) {
1194         BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
1195         goto err;
1196     }
1197
1198     if (!BN_copy(r, z))
1199         goto err;
1200     bn_check_top(r);
1201
1202     ret = 1;
1203
1204  err:
1205     BN_CTX_end(ctx);
1206     return ret;
1207 }
1208
1209 /*
1210  * Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns
1211  * 0. This function calls down to the BN_GF2m_mod_solve_quad_arr
1212  * implementation; this wrapper function is only provided for convenience;
1213  * for best performance, use the BN_GF2m_mod_solve_quad_arr function.
1214  */
1215 int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
1216                            BN_CTX *ctx)
1217 {
1218     int ret = 0;
1219     const int max = BN_num_bits(p) + 1;
1220     int *arr = NULL;
1221     bn_check_top(a);
1222     bn_check_top(p);
1223     if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
1224         goto err;
1225     ret = BN_GF2m_poly2arr(p, arr, max);
1226     if (!ret || ret > max) {
1227         BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH);
1228         goto err;
1229     }
1230     ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
1231     bn_check_top(r);
1232  err:
1233     OPENSSL_free(arr);
1234     return ret;
1235 }
1236
1237 /*
1238  * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i *
1239  * x^i) into an array of integers corresponding to the bits with non-zero
1240  * coefficient.  Array is terminated with -1. Up to max elements of the array
1241  * will be filled.  Return value is total number of array elements that would
1242  * be filled if array was large enough.
1243  */
1244 int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
1245 {
1246     int i, j, k = 0;
1247     BN_ULONG mask;
1248
1249     if (BN_is_zero(a))
1250         return 0;
1251
1252     for (i = a->top - 1; i >= 0; i--) {
1253         if (!a->d[i])
1254             /* skip word if a->d[i] == 0 */
1255             continue;
1256         mask = BN_TBIT;
1257         for (j = BN_BITS2 - 1; j >= 0; j--) {
1258             if (a->d[i] & mask) {
1259                 if (k < max)
1260                     p[k] = BN_BITS2 * i + j;
1261                 k++;
1262             }
1263             mask >>= 1;
1264         }
1265     }
1266
1267     if (k < max) {
1268         p[k] = -1;
1269         k++;
1270     }
1271
1272     return k;
1273 }
1274
1275 /*
1276  * Convert the coefficient array representation of a polynomial to a
1277  * bit-string.  The array must be terminated by -1.
1278  */
1279 int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
1280 {
1281     int i;
1282
1283     bn_check_top(a);
1284     BN_zero(a);
1285     for (i = 0; p[i] != -1; i++) {
1286         if (BN_set_bit(a, p[i]) == 0)
1287             return 0;
1288     }
1289     bn_check_top(a);
1290
1291     return 1;
1292 }
1293
1294 #endif