Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/bn/bn_mul.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/bn/bn_mul.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#ifndef BN_DEBUG
60
# undef NDEBUG                  /* avoid conflicting definitions */
61
# define NDEBUG
62
#endif
63
64
#include <stdio.h>
65
#include <assert.h>
66
#include "cryptlib.h"
67
#include "bn_lcl.h"
68
69
#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
70
/*
71
 * Here follows specialised variants of bn_add_words() and bn_sub_words().
72
 * They have the property performing operations on arrays of different sizes.
73
 * The sizes of those arrays is expressed through cl, which is the common
74
 * length ( basicall, min(len(a),len(b)) ), and dl, which is the delta
75
 * between the two lengths, calculated as len(a)-len(b). All lengths are the
76
 * number of BN_ULONGs...  For the operations that require a result array as
77
 * parameter, it must have the length cl+abs(dl). These functions should
78
 * probably end up in bn_asm.c as soon as there are assembler counterparts
79
 * for the systems that use assembler files.
80
 */
81
82
BN_ULONG bn_sub_part_words(BN_ULONG *r,
83
                           const BN_ULONG *a, const BN_ULONG *b,
84
                           int cl, int dl)
85
0
{
86
0
    BN_ULONG c, t;
87
88
0
    assert(cl >= 0);
89
0
    c = bn_sub_words(r, a, b, cl);
90
91
0
    if (dl == 0)
92
0
        return c;
93
94
0
    r += cl;
95
0
    a += cl;
96
0
    b += cl;
97
98
0
    if (dl < 0) {
99
# ifdef BN_COUNT
100
        fprintf(stderr, "  bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl,
101
                dl, c);
102
# endif
103
0
        for (;;) {
104
0
            t = b[0];
105
0
            r[0] = (0 - t - c) & BN_MASK2;
106
0
            if (t != 0)
107
0
                c = 1;
108
0
            if (++dl >= 0)
109
0
                break;
110
111
0
            t = b[1];
112
0
            r[1] = (0 - t - c) & BN_MASK2;
113
0
            if (t != 0)
114
0
                c = 1;
115
0
            if (++dl >= 0)
116
0
                break;
117
118
0
            t = b[2];
119
0
            r[2] = (0 - t - c) & BN_MASK2;
120
0
            if (t != 0)
121
0
                c = 1;
122
0
            if (++dl >= 0)
123
0
                break;
124
125
0
            t = b[3];
126
0
            r[3] = (0 - t - c) & BN_MASK2;
127
0
            if (t != 0)
128
0
                c = 1;
129
0
            if (++dl >= 0)
130
0
                break;
131
132
0
            b += 4;
133
0
            r += 4;
134
0
        }
135
0
    } else {
136
0
        int save_dl = dl;
137
# ifdef BN_COUNT
138
        fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl,
139
                dl, c);
140
# endif
141
0
        while (c) {
142
0
            t = a[0];
143
0
            r[0] = (t - c) & BN_MASK2;
144
0
            if (t != 0)
145
0
                c = 0;
146
0
            if (--dl <= 0)
147
0
                break;
148
149
0
            t = a[1];
150
0
            r[1] = (t - c) & BN_MASK2;
151
0
            if (t != 0)
152
0
                c = 0;
153
0
            if (--dl <= 0)
154
0
                break;
155
156
0
            t = a[2];
157
0
            r[2] = (t - c) & BN_MASK2;
158
0
            if (t != 0)
159
0
                c = 0;
160
0
            if (--dl <= 0)
161
0
                break;
162
163
0
            t = a[3];
164
0
            r[3] = (t - c) & BN_MASK2;
165
0
            if (t != 0)
166
0
                c = 0;
167
0
            if (--dl <= 0)
168
0
                break;
169
170
0
            save_dl = dl;
171
0
            a += 4;
172
0
            r += 4;
173
0
        }
174
0
        if (dl > 0) {
175
# ifdef BN_COUNT
176
            fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, c == 0)\n",
177
                    cl, dl);
178
# endif
179
0
            if (save_dl > dl) {
180
0
                switch (save_dl - dl) {
181
0
                case 1:
182
0
                    r[1] = a[1];
183
0
                    if (--dl <= 0)
184
0
                        break;
185
0
                case 2:
186
0
                    r[2] = a[2];
187
0
                    if (--dl <= 0)
188
0
                        break;
189
0
                case 3:
190
0
                    r[3] = a[3];
191
0
                    if (--dl <= 0)
192
0
                        break;
193
0
                }
194
0
                a += 4;
195
0
                r += 4;
196
0
            }
197
0
        }
198
0
        if (dl > 0) {
199
# ifdef BN_COUNT
200
            fprintf(stderr, "  bn_sub_part_words %d + %d (dl > 0, copy)\n",
201
                    cl, dl);
202
# endif
203
0
            for (;;) {
204
0
                r[0] = a[0];
205
0
                if (--dl <= 0)
206
0
                    break;
207
0
                r[1] = a[1];
208
0
                if (--dl <= 0)
209
0
                    break;
210
0
                r[2] = a[2];
211
0
                if (--dl <= 0)
212
0
                    break;
213
0
                r[3] = a[3];
214
0
                if (--dl <= 0)
215
0
                    break;
216
217
0
                a += 4;
218
0
                r += 4;
219
0
            }
220
0
        }
221
0
    }
222
0
    return c;
223
0
}
224
#endif
225
226
BN_ULONG bn_add_part_words(BN_ULONG *r,
227
                           const BN_ULONG *a, const BN_ULONG *b,
228
                           int cl, int dl)
229
0
{
230
0
    BN_ULONG c, l, t;
231
232
0
    assert(cl >= 0);
233
0
    c = bn_add_words(r, a, b, cl);
234
235
0
    if (dl == 0)
236
0
        return c;
237
238
0
    r += cl;
239
0
    a += cl;
240
0
    b += cl;
241
242
0
    if (dl < 0) {
243
0
        int save_dl = dl;
244
#ifdef BN_COUNT
245
        fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl,
246
                dl, c);
247
#endif
248
0
        while (c) {
249
0
            l = (c + b[0]) & BN_MASK2;
250
0
            c = (l < c);
251
0
            r[0] = l;
252
0
            if (++dl >= 0)
253
0
                break;
254
255
0
            l = (c + b[1]) & BN_MASK2;
256
0
            c = (l < c);
257
0
            r[1] = l;
258
0
            if (++dl >= 0)
259
0
                break;
260
261
0
            l = (c + b[2]) & BN_MASK2;
262
0
            c = (l < c);
263
0
            r[2] = l;
264
0
            if (++dl >= 0)
265
0
                break;
266
267
0
            l = (c + b[3]) & BN_MASK2;
268
0
            c = (l < c);
269
0
            r[3] = l;
270
0
            if (++dl >= 0)
271
0
                break;
272
273
0
            save_dl = dl;
274
0
            b += 4;
275
0
            r += 4;
276
0
        }
277
0
        if (dl < 0) {
278
#ifdef BN_COUNT
279
            fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, c == 0)\n",
280
                    cl, dl);
281
#endif
282
0
            if (save_dl < dl) {
283
0
                switch (dl - save_dl) {
284
0
                case 1:
285
0
                    r[1] = b[1];
286
0
                    if (++dl >= 0)
287
0
                        break;
288
0
                case 2:
289
0
                    r[2] = b[2];
290
0
                    if (++dl >= 0)
291
0
                        break;
292
0
                case 3:
293
0
                    r[3] = b[3];
294
0
                    if (++dl >= 0)
295
0
                        break;
296
0
                }
297
0
                b += 4;
298
0
                r += 4;
299
0
            }
300
0
        }
301
0
        if (dl < 0) {
302
#ifdef BN_COUNT
303
            fprintf(stderr, "  bn_add_part_words %d + %d (dl < 0, copy)\n",
304
                    cl, dl);
305
#endif
306
0
            for (;;) {
307
0
                r[0] = b[0];
308
0
                if (++dl >= 0)
309
0
                    break;
310
0
                r[1] = b[1];
311
0
                if (++dl >= 0)
312
0
                    break;
313
0
                r[2] = b[2];
314
0
                if (++dl >= 0)
315
0
                    break;
316
0
                r[3] = b[3];
317
0
                if (++dl >= 0)
318
0
                    break;
319
320
0
                b += 4;
321
0
                r += 4;
322
0
            }
323
0
        }
324
0
    } else {
325
0
        int save_dl = dl;
326
#ifdef BN_COUNT
327
        fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
328
#endif
329
0
        while (c) {
330
0
            t = (a[0] + c) & BN_MASK2;
331
0
            c = (t < c);
332
0
            r[0] = t;
333
0
            if (--dl <= 0)
334
0
                break;
335
336
0
            t = (a[1] + c) & BN_MASK2;
337
0
            c = (t < c);
338
0
            r[1] = t;
339
0
            if (--dl <= 0)
340
0
                break;
341
342
0
            t = (a[2] + c) & BN_MASK2;
343
0
            c = (t < c);
344
0
            r[2] = t;
345
0
            if (--dl <= 0)
346
0
                break;
347
348
0
            t = (a[3] + c) & BN_MASK2;
349
0
            c = (t < c);
350
0
            r[3] = t;
351
0
            if (--dl <= 0)
352
0
                break;
353
354
0
            save_dl = dl;
355
0
            a += 4;
356
0
            r += 4;
357
0
        }
358
#ifdef BN_COUNT
359
        fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl,
360
                dl);
361
#endif
362
0
        if (dl > 0) {
363
0
            if (save_dl > dl) {
364
0
                switch (save_dl - dl) {
365
0
                case 1:
366
0
                    r[1] = a[1];
367
0
                    if (--dl <= 0)
368
0
                        break;
369
0
                case 2:
370
0
                    r[2] = a[2];
371
0
                    if (--dl <= 0)
372
0
                        break;
373
0
                case 3:
374
0
                    r[3] = a[3];
375
0
                    if (--dl <= 0)
376
0
                        break;
377
0
                }
378
0
                a += 4;
379
0
                r += 4;
380
0
            }
381
0
        }
382
0
        if (dl > 0) {
383
#ifdef BN_COUNT
384
            fprintf(stderr, "  bn_add_part_words %d + %d (dl > 0, copy)\n",
385
                    cl, dl);
386
#endif
387
0
            for (;;) {
388
0
                r[0] = a[0];
389
0
                if (--dl <= 0)
390
0
                    break;
391
0
                r[1] = a[1];
392
0
                if (--dl <= 0)
393
0
                    break;
394
0
                r[2] = a[2];
395
0
                if (--dl <= 0)
396
0
                    break;
397
0
                r[3] = a[3];
398
0
                if (--dl <= 0)
399
0
                    break;
400
401
0
                a += 4;
402
0
                r += 4;
403
0
            }
404
0
        }
405
0
    }
406
0
    return c;
407
0
}
408
409
#ifdef BN_RECURSION
410
/*
411
 * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of
412
 * Computer Programming, Vol. 2)
413
 */
414
415
/*-
416
 * r is 2*n2 words in size,
417
 * a and b are both n2 words in size.
418
 * n2 must be a power of 2.
419
 * We multiply and return the result.
420
 * t must be 2*n2 words in size
421
 * We calculate
422
 * a[0]*b[0]
423
 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
424
 * a[1]*b[1]
425
 */
426
/* dnX may not be positive, but n2/2+dnX has to be */
427
void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
428
                      int dna, int dnb, BN_ULONG *t)
429
0
{
430
0
    int n = n2 / 2, c1, c2;
431
0
    int tna = n + dna, tnb = n + dnb;
432
0
    unsigned int neg, zero;
433
0
    BN_ULONG ln, lo, *p;
434
435
# ifdef BN_COUNT
436
    fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n", n2, dna, n2, dnb);
437
# endif
438
0
# ifdef BN_MUL_COMBA
439
#  if 0
440
    if (n2 == 4) {
441
        bn_mul_comba4(r, a, b);
442
        return;
443
    }
444
#  endif
445
    /*
446
     * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete
447
     * [steve]
448
     */
449
0
    if (n2 == 8 && dna == 0 && dnb == 0) {
450
0
        bn_mul_comba8(r, a, b);
451
0
        return;
452
0
    }
453
0
# endif                         /* BN_MUL_COMBA */
454
    /* Else do normal multiply */
455
0
    if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
456
0
        bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
457
0
        if ((dna + dnb) < 0)
458
0
            memset(&r[2 * n2 + dna + dnb], 0,
459
0
                   sizeof(BN_ULONG) * -(dna + dnb));
460
0
        return;
461
0
    }
462
    /* r=(a[0]-a[1])*(b[1]-b[0]) */
463
0
    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
464
0
    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
465
0
    zero = neg = 0;
466
0
    switch (c1 * 3 + c2) {
467
0
    case -4:
468
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
469
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
470
0
        break;
471
0
    case -3:
472
0
        zero = 1;
473
0
        break;
474
0
    case -2:
475
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
476
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
477
0
        neg = 1;
478
0
        break;
479
0
    case -1:
480
0
    case 0:
481
0
    case 1:
482
0
        zero = 1;
483
0
        break;
484
0
    case 2:
485
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
486
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
487
0
        neg = 1;
488
0
        break;
489
0
    case 3:
490
0
        zero = 1;
491
0
        break;
492
0
    case 4:
493
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
494
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
495
0
        break;
496
0
    }
497
498
0
# ifdef BN_MUL_COMBA
499
0
    if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take
500
                                           * extra args to do this well */
501
0
        if (!zero)
502
0
            bn_mul_comba4(&(t[n2]), t, &(t[n]));
503
0
        else
504
0
            memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
505
506
0
        bn_mul_comba4(r, a, b);
507
0
        bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
508
0
    } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could
509
                                                  * take extra args to do
510
                                                  * this well */
511
0
        if (!zero)
512
0
            bn_mul_comba8(&(t[n2]), t, &(t[n]));
513
0
        else
514
0
            memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
515
516
0
        bn_mul_comba8(r, a, b);
517
0
        bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
518
0
    } else
519
0
# endif                         /* BN_MUL_COMBA */
520
0
    {
521
0
        p = &(t[n2 * 2]);
522
0
        if (!zero)
523
0
            bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
524
0
        else
525
0
            memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
526
0
        bn_mul_recursive(r, a, b, n, 0, 0, p);
527
0
        bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
528
0
    }
529
530
    /*-
531
     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
532
     * r[10] holds (a[0]*b[0])
533
     * r[32] holds (b[1]*b[1])
534
     */
535
536
0
    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
537
538
0
    if (neg) {                  /* if t[32] is negative */
539
0
        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
540
0
    } else {
541
        /* Might have a carry */
542
0
        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
543
0
    }
544
545
    /*-
546
     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
547
     * r[10] holds (a[0]*b[0])
548
     * r[32] holds (b[1]*b[1])
549
     * c1 holds the carry bits
550
     */
551
0
    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
552
0
    if (c1) {
553
0
        p = &(r[n + n2]);
554
0
        lo = *p;
555
0
        ln = (lo + c1) & BN_MASK2;
556
0
        *p = ln;
557
558
        /*
559
         * The overflow will stop before we over write words we should not
560
         * overwrite
561
         */
562
0
        if (ln < (BN_ULONG)c1) {
563
0
            do {
564
0
                p++;
565
0
                lo = *p;
566
0
                ln = (lo + 1) & BN_MASK2;
567
0
                *p = ln;
568
0
            } while (ln == 0);
569
0
        }
570
0
    }
571
0
}
572
573
/*
574
 * n+tn is the word length t needs to be n*4 is size, as does r
575
 */
576
/* tnX may not be negative but less than n */
577
void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
578
                           int tna, int tnb, BN_ULONG *t)
579
0
{
580
0
    int i, j, n2 = n * 2;
581
0
    int c1, c2, neg;
582
0
    BN_ULONG ln, lo, *p;
583
584
# ifdef BN_COUNT
585
    fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
586
            n, tna, n, tnb);
587
# endif
588
0
    if (n < 8) {
589
0
        bn_mul_normal(r, a, n + tna, b, n + tnb);
590
0
        return;
591
0
    }
592
593
    /* r=(a[0]-a[1])*(b[1]-b[0]) */
594
0
    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
595
0
    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
596
0
    neg = 0;
597
0
    switch (c1 * 3 + c2) {
598
0
    case -4:
599
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
600
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
601
0
        break;
602
0
    case -3:
603
        /* break; */
604
0
    case -2:
605
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
606
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
607
0
        neg = 1;
608
0
        break;
609
0
    case -1:
610
0
    case 0:
611
0
    case 1:
612
        /* break; */
613
0
    case 2:
614
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
615
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
616
0
        neg = 1;
617
0
        break;
618
0
    case 3:
619
        /* break; */
620
0
    case 4:
621
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
622
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
623
0
        break;
624
0
    }
625
    /*
626
     * The zero case isn't yet implemented here. The speedup would probably
627
     * be negligible.
628
     */
629
# if 0
630
    if (n == 4) {
631
        bn_mul_comba4(&(t[n2]), t, &(t[n]));
632
        bn_mul_comba4(r, a, b);
633
        bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
634
        memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2));
635
    } else
636
# endif
637
0
    if (n == 8) {
638
0
        bn_mul_comba8(&(t[n2]), t, &(t[n]));
639
0
        bn_mul_comba8(r, a, b);
640
0
        bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
641
0
        memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb));
642
0
    } else {
643
0
        p = &(t[n2 * 2]);
644
0
        bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
645
0
        bn_mul_recursive(r, a, b, n, 0, 0, p);
646
0
        i = n / 2;
647
        /*
648
         * If there is only a bottom half to the number, just do it
649
         */
650
0
        if (tna > tnb)
651
0
            j = tna - i;
652
0
        else
653
0
            j = tnb - i;
654
0
        if (j == 0) {
655
0
            bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
656
0
                             i, tna - i, tnb - i, p);
657
0
            memset(&(r[n2 + i * 2]), 0, sizeof(BN_ULONG) * (n2 - i * 2));
658
0
        } else if (j > 0) {     /* eg, n == 16, i == 8 and tn == 11 */
659
0
            bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
660
0
                                  i, tna - i, tnb - i, p);
661
0
            memset(&(r[n2 + tna + tnb]), 0,
662
0
                   sizeof(BN_ULONG) * (n2 - tna - tnb));
663
0
        } else {                /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
664
665
0
            memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2);
666
0
            if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
667
0
                && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
668
0
                bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
669
0
            } else {
670
0
                for (;;) {
671
0
                    i /= 2;
672
                    /*
673
                     * these simplified conditions work exclusively because
674
                     * difference between tna and tnb is 1 or 0
675
                     */
676
0
                    if (i < tna || i < tnb) {
677
0
                        bn_mul_part_recursive(&(r[n2]),
678
0
                                              &(a[n]), &(b[n]),
679
0
                                              i, tna - i, tnb - i, p);
680
0
                        break;
681
0
                    } else if (i == tna || i == tnb) {
682
0
                        bn_mul_recursive(&(r[n2]),
683
0
                                         &(a[n]), &(b[n]),
684
0
                                         i, tna - i, tnb - i, p);
685
0
                        break;
686
0
                    }
687
0
                }
688
0
            }
689
0
        }
690
0
    }
691
692
    /*-
693
     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
694
     * r[10] holds (a[0]*b[0])
695
     * r[32] holds (b[1]*b[1])
696
     */
697
698
0
    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
699
700
0
    if (neg) {                  /* if t[32] is negative */
701
0
        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
702
0
    } else {
703
        /* Might have a carry */
704
0
        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
705
0
    }
706
707
    /*-
708
     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
709
     * r[10] holds (a[0]*b[0])
710
     * r[32] holds (b[1]*b[1])
711
     * c1 holds the carry bits
712
     */
713
0
    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
714
0
    if (c1) {
715
0
        p = &(r[n + n2]);
716
0
        lo = *p;
717
0
        ln = (lo + c1) & BN_MASK2;
718
0
        *p = ln;
719
720
        /*
721
         * The overflow will stop before we over write words we should not
722
         * overwrite
723
         */
724
0
        if (ln < (BN_ULONG)c1) {
725
0
            do {
726
0
                p++;
727
0
                lo = *p;
728
0
                ln = (lo + 1) & BN_MASK2;
729
0
                *p = ln;
730
0
            } while (ln == 0);
731
0
        }
732
0
    }
733
0
}
734
735
/*-
736
 * a and b must be the same size, which is n2.
737
 * r needs to be n2 words and t needs to be n2*2
738
 */
739
void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
740
                          BN_ULONG *t)
741
0
{
742
0
    int n = n2 / 2;
743
744
# ifdef BN_COUNT
745
    fprintf(stderr, " bn_mul_low_recursive %d * %d\n", n2, n2);
746
# endif
747
748
0
    bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
749
0
    if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
750
0
        bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
751
0
        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
752
0
        bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
753
0
        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
754
0
    } else {
755
0
        bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
756
0
        bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
757
0
        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
758
0
        bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
759
0
    }
760
0
}
761
762
/*-
763
 * a and b must be the same size, which is n2.
764
 * r needs to be n2 words and t needs to be n2*2
765
 * l is the low words of the output.
766
 * t needs to be n2*3
767
 */
768
void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
769
                 BN_ULONG *t)
770
0
{
771
0
    int i, n;
772
0
    int c1, c2;
773
0
    int neg, oneg, zero;
774
0
    BN_ULONG ll, lc, *lp, *mp;
775
776
# ifdef BN_COUNT
777
    fprintf(stderr, " bn_mul_high %d * %d\n", n2, n2);
778
# endif
779
0
    n = n2 / 2;
780
781
    /* Calculate (al-ah)*(bh-bl) */
782
0
    neg = zero = 0;
783
0
    c1 = bn_cmp_words(&(a[0]), &(a[n]), n);
784
0
    c2 = bn_cmp_words(&(b[n]), &(b[0]), n);
785
0
    switch (c1 * 3 + c2) {
786
0
    case -4:
787
0
        bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
788
0
        bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
789
0
        break;
790
0
    case -3:
791
0
        zero = 1;
792
0
        break;
793
0
    case -2:
794
0
        bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
795
0
        bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
796
0
        neg = 1;
797
0
        break;
798
0
    case -1:
799
0
    case 0:
800
0
    case 1:
801
0
        zero = 1;
802
0
        break;
803
0
    case 2:
804
0
        bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
805
0
        bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
806
0
        neg = 1;
807
0
        break;
808
0
    case 3:
809
0
        zero = 1;
810
0
        break;
811
0
    case 4:
812
0
        bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
813
0
        bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
814
0
        break;
815
0
    }
816
817
0
    oneg = neg;
818
    /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
819
    /* r[10] = (a[1]*b[1]) */
820
0
# ifdef BN_MUL_COMBA
821
0
    if (n == 8) {
822
0
        bn_mul_comba8(&(t[0]), &(r[0]), &(r[n]));
823
0
        bn_mul_comba8(r, &(a[n]), &(b[n]));
824
0
    } else
825
0
# endif
826
0
    {
827
0
        bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2]));
828
0
        bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2]));
829
0
    }
830
831
    /*-
832
     * s0 == low(al*bl)
833
     * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
834
     * We know s0 and s1 so the only unknown is high(al*bl)
835
     * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
836
     * high(al*bl) == s1 - (r[0]+l[0]+t[0])
837
     */
838
0
    if (l != NULL) {
839
0
        lp = &(t[n2 + n]);
840
0
        c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n));
841
0
    } else {
842
0
        c1 = 0;
843
0
        lp = &(r[0]);
844
0
    }
845
846
0
    if (neg)
847
0
        neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n));
848
0
    else {
849
0
        bn_add_words(&(t[n2]), lp, &(t[0]), n);
850
0
        neg = 0;
851
0
    }
852
853
0
    if (l != NULL) {
854
0
        bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n);
855
0
    } else {
856
0
        lp = &(t[n2 + n]);
857
0
        mp = &(t[n2]);
858
0
        for (i = 0; i < n; i++)
859
0
            lp[i] = ((~mp[i]) + 1) & BN_MASK2;
860
0
    }
861
862
    /*-
863
     * s[0] = low(al*bl)
864
     * t[3] = high(al*bl)
865
     * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
866
     * r[10] = (a[1]*b[1])
867
     */
868
    /*-
869
     * R[10] = al*bl
870
     * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
871
     * R[32] = ah*bh
872
     */
873
    /*-
874
     * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
875
     * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
876
     * R[3]=r[1]+(carry/borrow)
877
     */
878
0
    if (l != NULL) {
879
0
        lp = &(t[n2]);
880
0
        c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n));
881
0
    } else {
882
0
        lp = &(t[n2 + n]);
883
0
        c1 = 0;
884
0
    }
885
0
    c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n));
886
0
    if (oneg)
887
0
        c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n));
888
0
    else
889
0
        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n));
890
891
0
    c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n));
892
0
    c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n));
893
0
    if (oneg)
894
0
        c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n));
895
0
    else
896
0
        c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n));
897
898
0
    if (c1 != 0) {              /* Add starting at r[0], could be +ve or -ve */
899
0
        i = 0;
900
0
        if (c1 > 0) {
901
0
            lc = c1;
902
0
            do {
903
0
                ll = (r[i] + lc) & BN_MASK2;
904
0
                r[i++] = ll;
905
0
                lc = (lc > ll);
906
0
            } while (lc);
907
0
        } else {
908
0
            lc = -c1;
909
0
            do {
910
0
                ll = r[i];
911
0
                r[i++] = (ll - lc) & BN_MASK2;
912
0
                lc = (lc > ll);
913
0
            } while (lc);
914
0
        }
915
0
    }
916
0
    if (c2 != 0) {              /* Add starting at r[1] */
917
0
        i = n;
918
0
        if (c2 > 0) {
919
0
            lc = c2;
920
0
            do {
921
0
                ll = (r[i] + lc) & BN_MASK2;
922
0
                r[i++] = ll;
923
0
                lc = (lc > ll);
924
0
            } while (lc);
925
0
        } else {
926
0
            lc = -c2;
927
0
            do {
928
0
                ll = r[i];
929
0
                r[i++] = (ll - lc) & BN_MASK2;
930
0
                lc = (lc > ll);
931
0
            } while (lc);
932
0
        }
933
0
    }
934
0
}
935
#endif                          /* BN_RECURSION */
936
937
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
938
0
{
939
0
    int ret = 0;
940
0
    int top, al, bl;
941
0
    BIGNUM *rr;
942
0
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
943
0
    int i;
944
0
#endif
945
0
#ifdef BN_RECURSION
946
0
    BIGNUM *t = NULL;
947
0
    int j = 0, k;
948
0
#endif
949
950
#ifdef BN_COUNT
951
    fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top);
952
#endif
953
954
0
    bn_check_top(a);
955
0
    bn_check_top(b);
956
0
    bn_check_top(r);
957
958
0
    al = a->top;
959
0
    bl = b->top;
960
961
0
    if ((al == 0) || (bl == 0)) {
962
0
        BN_zero(r);
963
0
        return (1);
964
0
    }
965
0
    top = al + bl;
966
967
0
    BN_CTX_start(ctx);
968
0
    if ((r == a) || (r == b)) {
969
0
        if ((rr = BN_CTX_get(ctx)) == NULL)
970
0
            goto err;
971
0
    } else
972
0
        rr = r;
973
0
    rr->neg = a->neg ^ b->neg;
974
975
0
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
976
0
    i = al - bl;
977
0
#endif
978
0
#ifdef BN_MUL_COMBA
979
0
    if (i == 0) {
980
# if 0
981
        if (al == 4) {
982
            if (bn_wexpand(rr, 8) == NULL)
983
                goto err;
984
            rr->top = 8;
985
            bn_mul_comba4(rr->d, a->d, b->d);
986
            goto end;
987
        }
988
# endif
989
0
        if (al == 8) {
990
0
            if (bn_wexpand(rr, 16) == NULL)
991
0
                goto err;
992
0
            rr->top = 16;
993
0
            bn_mul_comba8(rr->d, a->d, b->d);
994
0
            goto end;
995
0
        }
996
0
    }
997
0
#endif                          /* BN_MUL_COMBA */
998
0
#ifdef BN_RECURSION
999
0
    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
1000
0
        if (i >= -1 && i <= 1) {
1001
            /*
1002
             * Find out the power of two lower or equal to the longest of the
1003
             * two numbers
1004
             */
1005
0
            if (i >= 0) {
1006
0
                j = BN_num_bits_word((BN_ULONG)al);
1007
0
            }
1008
0
            if (i == -1) {
1009
0
                j = BN_num_bits_word((BN_ULONG)bl);
1010
0
            }
1011
0
            j = 1 << (j - 1);
1012
0
            assert(j <= al || j <= bl);
1013
0
            k = j + j;
1014
0
            t = BN_CTX_get(ctx);
1015
0
            if (t == NULL)
1016
0
                goto err;
1017
0
            if (al > j || bl > j) {
1018
0
                if (bn_wexpand(t, k * 4) == NULL)
1019
0
                    goto err;
1020
0
                if (bn_wexpand(rr, k * 4) == NULL)
1021
0
                    goto err;
1022
0
                bn_mul_part_recursive(rr->d, a->d, b->d,
1023
0
                                      j, al - j, bl - j, t->d);
1024
0
            } else {            /* al <= j || bl <= j */
1025
1026
0
                if (bn_wexpand(t, k * 2) == NULL)
1027
0
                    goto err;
1028
0
                if (bn_wexpand(rr, k * 2) == NULL)
1029
0
                    goto err;
1030
0
                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
1031
0
            }
1032
0
            rr->top = top;
1033
0
            goto end;
1034
0
        }
1035
0
    }
1036
0
#endif                          /* BN_RECURSION */
1037
0
    if (bn_wexpand(rr, top) == NULL)
1038
0
        goto err;
1039
0
    rr->top = top;
1040
0
    bn_mul_normal(rr->d, a->d, al, b->d, bl);
1041
1042
0
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
1043
0
 end:
1044
0
#endif
1045
0
    bn_correct_top(rr);
1046
0
    if (r != rr && BN_copy(r, rr) == NULL)
1047
0
        goto err;
1048
1049
0
    ret = 1;
1050
0
 err:
1051
0
    bn_check_top(r);
1052
0
    BN_CTX_end(ctx);
1053
0
    return (ret);
1054
0
}
1055
1056
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
1057
0
{
1058
0
    BN_ULONG *rr;
1059
1060
#ifdef BN_COUNT
1061
    fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb);
1062
#endif
1063
1064
0
    if (na < nb) {
1065
0
        int itmp;
1066
0
        BN_ULONG *ltmp;
1067
1068
0
        itmp = na;
1069
0
        na = nb;
1070
0
        nb = itmp;
1071
0
        ltmp = a;
1072
0
        a = b;
1073
0
        b = ltmp;
1074
1075
0
    }
1076
0
    rr = &(r[na]);
1077
0
    if (nb <= 0) {
1078
0
        (void)bn_mul_words(r, a, na, 0);
1079
0
        return;
1080
0
    } else
1081
0
        rr[0] = bn_mul_words(r, a, na, b[0]);
1082
1083
0
    for (;;) {
1084
0
        if (--nb <= 0)
1085
0
            return;
1086
0
        rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
1087
0
        if (--nb <= 0)
1088
0
            return;
1089
0
        rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
1090
0
        if (--nb <= 0)
1091
0
            return;
1092
0
        rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
1093
0
        if (--nb <= 0)
1094
0
            return;
1095
0
        rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
1096
0
        rr += 4;
1097
0
        r += 4;
1098
0
        b += 4;
1099
0
    }
1100
0
}
1101
1102
void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
1103
0
{
1104
#ifdef BN_COUNT
1105
    fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n);
1106
#endif
1107
0
    bn_mul_words(r, a, n, b[0]);
1108
1109
0
    for (;;) {
1110
0
        if (--n <= 0)
1111
0
            return;
1112
0
        bn_mul_add_words(&(r[1]), a, n, b[1]);
1113
0
        if (--n <= 0)
1114
0
            return;
1115
0
        bn_mul_add_words(&(r[2]), a, n, b[2]);
1116
0
        if (--n <= 0)
1117
0
            return;
1118
0
        bn_mul_add_words(&(r[3]), a, n, b[3]);
1119
0
        if (--n <= 0)
1120
0
            return;
1121
0
        bn_mul_add_words(&(r[4]), a, n, b[4]);
1122
0
        r += 4;
1123
0
        b += 4;
1124
0
    }
1125
0
}