Coverage Report

Created: 2022-11-30 06:20

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