Coverage Report

Created: 2026-02-22 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/bn/bn_mul.c
Line
Count
Source
1
/*
2
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <assert.h>
11
#include "internal/cryptlib.h"
12
#include "bn_local.h"
13
14
#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
15
/*
16
 * Here follows specialised variants of bn_add_words() and bn_sub_words().
17
 * They have the property performing operations on arrays of different sizes.
18
 * The sizes of those arrays is expressed through cl, which is the common
19
 * length ( basically, min(len(a),len(b)) ), and dl, which is the delta
20
 * between the two lengths, calculated as len(a)-len(b). All lengths are the
21
 * number of BN_ULONGs...  For the operations that require a result array as
22
 * parameter, it must have the length cl+abs(dl). These functions should
23
 * probably end up in bn_asm.c as soon as there are assembler counterparts
24
 * for the systems that use assembler files.
25
 */
26
27
BN_ULONG bn_sub_part_words(BN_ULONG *r,
28
    const BN_ULONG *a, const BN_ULONG *b,
29
    int cl, int dl)
30
0
{
31
0
    BN_ULONG c, t;
32
33
0
    assert(cl >= 0);
34
0
    c = bn_sub_words(r, a, b, cl);
35
36
0
    if (dl == 0)
37
0
        return c;
38
39
0
    r += cl;
40
0
    a += cl;
41
0
    b += cl;
42
43
0
    if (dl < 0) {
44
0
        for (;;) {
45
0
            t = b[0];
46
0
            r[0] = (0 - t - c) & BN_MASK2;
47
0
            if (t != 0)
48
0
                c = 1;
49
0
            if (++dl >= 0)
50
0
                break;
51
52
0
            t = b[1];
53
0
            r[1] = (0 - t - c) & BN_MASK2;
54
0
            if (t != 0)
55
0
                c = 1;
56
0
            if (++dl >= 0)
57
0
                break;
58
59
0
            t = b[2];
60
0
            r[2] = (0 - t - c) & BN_MASK2;
61
0
            if (t != 0)
62
0
                c = 1;
63
0
            if (++dl >= 0)
64
0
                break;
65
66
0
            t = b[3];
67
0
            r[3] = (0 - t - c) & BN_MASK2;
68
0
            if (t != 0)
69
0
                c = 1;
70
0
            if (++dl >= 0)
71
0
                break;
72
73
0
            b += 4;
74
0
            r += 4;
75
0
        }
76
0
    } else {
77
0
        int save_dl = dl;
78
0
        while (c) {
79
0
            t = a[0];
80
0
            r[0] = (t - c) & BN_MASK2;
81
0
            if (t != 0)
82
0
                c = 0;
83
0
            if (--dl <= 0)
84
0
                break;
85
86
0
            t = a[1];
87
0
            r[1] = (t - c) & BN_MASK2;
88
0
            if (t != 0)
89
0
                c = 0;
90
0
            if (--dl <= 0)
91
0
                break;
92
93
0
            t = a[2];
94
0
            r[2] = (t - c) & BN_MASK2;
95
0
            if (t != 0)
96
0
                c = 0;
97
0
            if (--dl <= 0)
98
0
                break;
99
100
0
            t = a[3];
101
0
            r[3] = (t - c) & BN_MASK2;
102
0
            if (t != 0)
103
0
                c = 0;
104
0
            if (--dl <= 0)
105
0
                break;
106
107
0
            save_dl = dl;
108
0
            a += 4;
109
0
            r += 4;
110
0
        }
111
0
        if (dl > 0) {
112
0
            if (save_dl > dl) {
113
0
                switch (save_dl - dl) {
114
0
                case 1:
115
0
                    r[1] = a[1];
116
0
                    if (--dl <= 0)
117
0
                        break;
118
                    /* fall through */
119
0
                case 2:
120
0
                    r[2] = a[2];
121
0
                    if (--dl <= 0)
122
0
                        break;
123
                    /* fall through */
124
0
                case 3:
125
0
                    r[3] = a[3];
126
0
                    if (--dl <= 0)
127
0
                        break;
128
0
                }
129
0
                a += 4;
130
0
                r += 4;
131
0
            }
132
0
        }
133
0
        if (dl > 0) {
134
0
            for (;;) {
135
0
                r[0] = a[0];
136
0
                if (--dl <= 0)
137
0
                    break;
138
0
                r[1] = a[1];
139
0
                if (--dl <= 0)
140
0
                    break;
141
0
                r[2] = a[2];
142
0
                if (--dl <= 0)
143
0
                    break;
144
0
                r[3] = a[3];
145
0
                if (--dl <= 0)
146
0
                    break;
147
148
0
                a += 4;
149
0
                r += 4;
150
0
            }
151
0
        }
152
0
    }
153
0
    return c;
154
0
}
155
#endif
156
157
#ifndef OPENSSL_SMALL_FOOTPRINT
158
/*
159
 * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of
160
 * Computer Programming, Vol. 2)
161
 */
162
163
/*-
164
 * r is 2*n2 words in size,
165
 * a and b are both n2 words in size.
166
 * n2 must be a power of 2.
167
 * We multiply and return the result.
168
 * t must be 2*n2 words in size
169
 * We calculate
170
 * a[0]*b[0]
171
 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
172
 * a[1]*b[1]
173
 */
174
/* dnX may not be positive, but n2/2+dnX has to be */
175
void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
176
    int dna, int dnb, BN_ULONG *t)
177
0
{
178
0
    int n = n2 / 2, c1, c2;
179
0
    int tna = n + dna, tnb = n + dnb;
180
0
    unsigned int neg, zero;
181
0
    BN_ULONG ln, lo, *p;
182
183
    /*
184
     * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete
185
     * [steve]
186
     */
187
0
    if (n2 == 8 && dna == 0 && dnb == 0) {
188
0
        bn_mul_comba8(r, a, b);
189
0
        return;
190
0
    }
191
192
    /* Else do normal multiply */
193
0
    if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
194
0
        bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
195
0
        if ((dna + dnb) < 0)
196
0
            memset(&r[2 * n2 + dna + dnb], 0,
197
0
                sizeof(BN_ULONG) * -(dna + dnb));
198
0
        return;
199
0
    }
200
    /* r=(a[0]-a[1])*(b[1]-b[0]) */
201
0
    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
202
0
    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
203
0
    zero = neg = 0;
204
0
    switch (c1 * 3 + c2) {
205
0
    case -4:
206
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
207
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
208
0
        break;
209
0
    case -3:
210
0
        zero = 1;
211
0
        break;
212
0
    case -2:
213
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
214
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
215
0
        neg = 1;
216
0
        break;
217
0
    case -1:
218
0
    case 0:
219
0
    case 1:
220
0
        zero = 1;
221
0
        break;
222
0
    case 2:
223
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
224
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
225
0
        neg = 1;
226
0
        break;
227
0
    case 3:
228
0
        zero = 1;
229
0
        break;
230
0
    case 4:
231
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
232
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
233
0
        break;
234
0
    }
235
236
0
    if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take
237
                                           * extra args to do this well */
238
0
        if (!zero)
239
0
            bn_mul_comba4(&(t[n2]), t, &(t[n]));
240
0
        else
241
0
            memset(&t[n2], 0, sizeof(*t) * 8);
242
243
0
        bn_mul_comba4(r, a, b);
244
0
        bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
245
0
    } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could
246
                                                  * take extra args to do
247
                                                  * this well */
248
0
        if (!zero)
249
0
            bn_mul_comba8(&(t[n2]), t, &(t[n]));
250
0
        else
251
0
            memset(&t[n2], 0, sizeof(*t) * 16);
252
253
0
        bn_mul_comba8(r, a, b);
254
0
        bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
255
0
    } else {
256
0
        p = &(t[n2 * 2]);
257
0
        if (!zero)
258
0
            bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
259
0
        else
260
0
            memset(&t[n2], 0, sizeof(*t) * n2);
261
0
        bn_mul_recursive(r, a, b, n, 0, 0, p);
262
0
        bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
263
0
    }
264
265
    /*-
266
     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
267
     * r[10] holds (a[0]*b[0])
268
     * r[32] holds (b[1]*b[1])
269
     */
270
271
0
    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
272
273
0
    if (neg) { /* if t[32] is negative */
274
0
        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
275
0
    } else {
276
        /* Might have a carry */
277
0
        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
278
0
    }
279
280
    /*-
281
     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
282
     * r[10] holds (a[0]*b[0])
283
     * r[32] holds (b[1]*b[1])
284
     * c1 holds the carry bits
285
     */
286
0
    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
287
0
    if (c1) {
288
0
        p = &(r[n + n2]);
289
0
        lo = *p;
290
0
        ln = (lo + c1) & BN_MASK2;
291
0
        *p = ln;
292
293
        /*
294
         * The overflow will stop before we over write words we should not
295
         * overwrite
296
         */
297
0
        if (ln < (BN_ULONG)c1) {
298
0
            do {
299
0
                p++;
300
0
                lo = *p;
301
0
                ln = (lo + 1) & BN_MASK2;
302
0
                *p = ln;
303
0
            } while (ln == 0);
304
0
        }
305
0
    }
306
0
}
307
308
/*
309
 * n+tn is the word length t needs to be n*4 is size, as does r
310
 */
311
/* tnX may not be negative but less than n */
312
void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
313
    int tna, int tnb, BN_ULONG *t)
314
0
{
315
0
    int i, j, n2 = n * 2;
316
0
    int c1, c2, neg;
317
0
    BN_ULONG ln, lo, *p;
318
319
0
    if (n < 8) {
320
0
        bn_mul_normal(r, a, n + tna, b, n + tnb);
321
0
        return;
322
0
    }
323
324
    /* r=(a[0]-a[1])*(b[1]-b[0]) */
325
0
    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
326
0
    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
327
0
    neg = 0;
328
0
    switch (c1 * 3 + c2) {
329
0
    case -4:
330
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
331
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
332
0
        break;
333
0
    case -3:
334
0
    case -2:
335
0
        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
336
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
337
0
        neg = 1;
338
0
        break;
339
0
    case -1:
340
0
    case 0:
341
0
    case 1:
342
0
    case 2:
343
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
344
0
        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
345
0
        neg = 1;
346
0
        break;
347
0
    case 3:
348
0
    case 4:
349
0
        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
350
0
        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
351
0
        break;
352
0
    }
353
    /*
354
     * The zero case isn't yet implemented here. The speedup would probably
355
     * be negligible.
356
     */
357
#if 0
358
    if (n == 4) {
359
        bn_mul_comba4(&(t[n2]), t, &(t[n]));
360
        bn_mul_comba4(r, a, b);
361
        bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
362
        memset(&r[n2 + tn * 2], 0, sizeof(*r) * (n2 - tn * 2));
363
    } else
364
#endif
365
0
    if (n == 8) {
366
0
        bn_mul_comba8(&(t[n2]), t, &(t[n]));
367
0
        bn_mul_comba8(r, a, b);
368
0
        bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
369
0
        memset(&r[n2 + tna + tnb], 0, sizeof(*r) * (n2 - tna - tnb));
370
0
    } else {
371
0
        p = &(t[n2 * 2]);
372
0
        bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
373
0
        bn_mul_recursive(r, a, b, n, 0, 0, p);
374
0
        i = n / 2;
375
        /*
376
         * If there is only a bottom half to the number, just do it
377
         */
378
0
        if (tna > tnb)
379
0
            j = tna - i;
380
0
        else
381
0
            j = tnb - i;
382
0
        if (j == 0) {
383
0
            bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
384
0
                i, tna - i, tnb - i, p);
385
0
            memset(&r[n2 + i * 2], 0, sizeof(*r) * (n2 - i * 2));
386
0
        } else if (j > 0) { /* eg, n == 16, i == 8 and tn == 11 */
387
0
            bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
388
0
                i, tna - i, tnb - i, p);
389
0
            memset(&(r[n2 + tna + tnb]), 0,
390
0
                sizeof(BN_ULONG) * (n2 - tna - tnb));
391
0
        } else { /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
392
393
0
            memset(&r[n2], 0, sizeof(*r) * n2);
394
0
            if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
395
0
                && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
396
0
                bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
397
0
            } else {
398
0
                for (;;) {
399
0
                    i /= 2;
400
                    /*
401
                     * these simplified conditions work exclusively because
402
                     * difference between tna and tnb is 1 or 0
403
                     */
404
0
                    if (i < tna || i < tnb) {
405
0
                        bn_mul_part_recursive(&(r[n2]),
406
0
                            &(a[n]), &(b[n]),
407
0
                            i, tna - i, tnb - i, p);
408
0
                        break;
409
0
                    } else if (i == tna || i == tnb) {
410
0
                        bn_mul_recursive(&(r[n2]),
411
0
                            &(a[n]), &(b[n]),
412
0
                            i, tna - i, tnb - i, p);
413
0
                        break;
414
0
                    }
415
0
                }
416
0
            }
417
0
        }
418
0
    }
419
420
    /*-
421
     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
422
     * r[10] holds (a[0]*b[0])
423
     * r[32] holds (b[1]*b[1])
424
     */
425
426
0
    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
427
428
0
    if (neg) { /* if t[32] is negative */
429
0
        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
430
0
    } else {
431
        /* Might have a carry */
432
0
        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
433
0
    }
434
435
    /*-
436
     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
437
     * r[10] holds (a[0]*b[0])
438
     * r[32] holds (b[1]*b[1])
439
     * c1 holds the carry bits
440
     */
441
0
    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
442
0
    if (c1) {
443
0
        p = &(r[n + n2]);
444
0
        lo = *p;
445
0
        ln = (lo + c1) & BN_MASK2;
446
0
        *p = ln;
447
448
        /*
449
         * The overflow will stop before we over write words we should not
450
         * overwrite
451
         */
452
0
        if (ln < (BN_ULONG)c1) {
453
0
            do {
454
0
                p++;
455
0
                lo = *p;
456
0
                ln = (lo + 1) & BN_MASK2;
457
0
                *p = ln;
458
0
            } while (ln == 0);
459
0
        }
460
0
    }
461
0
}
462
463
/*-
464
 * a and b must be the same size, which is n2.
465
 * r needs to be n2 words and t needs to be n2*2
466
 */
467
void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
468
    BN_ULONG *t)
469
0
{
470
0
    int n = n2 / 2;
471
472
0
    bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
473
0
    if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
474
0
        bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
475
0
        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
476
0
        bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
477
0
        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
478
0
    } else {
479
0
        bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
480
0
        bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
481
0
        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
482
0
        bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
483
0
    }
484
0
}
485
#endif /* OPENSSL_SMALL_FOOTPRINT */
486
487
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
488
0
{
489
0
    int ret = bn_mul_fixed_top(r, a, b, ctx);
490
491
0
    bn_correct_top(r);
492
0
    bn_check_top(r);
493
494
0
    return ret;
495
0
}
496
497
int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
498
0
{
499
0
    int ret = 0;
500
0
    int top, al, bl;
501
0
    BIGNUM *rr;
502
0
#if !defined(OPENSSL_SMALL_FOOTPRINT)
503
0
    int i;
504
0
    BIGNUM *t = NULL;
505
0
    int j = 0, k;
506
0
#endif
507
508
0
    bn_check_top(a);
509
0
    bn_check_top(b);
510
0
    bn_check_top(r);
511
512
0
    al = a->top;
513
0
    bl = b->top;
514
515
0
    if ((al == 0) || (bl == 0)) {
516
0
        BN_zero(r);
517
0
        return 1;
518
0
    }
519
0
    top = al + bl;
520
521
0
    BN_CTX_start(ctx);
522
0
    if ((r == a) || (r == b)) {
523
0
        if ((rr = BN_CTX_get(ctx)) == NULL)
524
0
            goto err;
525
0
    } else
526
0
        rr = r;
527
528
0
#if !defined(OPENSSL_SMALL_FOOTPRINT)
529
0
    i = al - bl;
530
531
0
    if (i == 0) {
532
#if 0
533
        if (al == 4) {
534
            if (bn_wexpand(rr, 8) == NULL)
535
                goto err;
536
            rr->top = 8;
537
            bn_mul_comba4(rr->d, a->d, b->d);
538
            goto end;
539
        }
540
#endif
541
0
        if (al == 8) {
542
0
            if (bn_wexpand(rr, 16) == NULL)
543
0
                goto err;
544
0
            rr->top = 16;
545
0
            bn_mul_comba8(rr->d, a->d, b->d);
546
0
            goto end;
547
0
        }
548
0
    }
549
550
0
    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
551
0
        if (i >= -1 && i <= 1) {
552
            /*
553
             * Find out the power of two lower or equal to the longest of the
554
             * two numbers
555
             */
556
0
            if (i >= 0) {
557
0
                j = BN_num_bits_word((BN_ULONG)al);
558
0
            }
559
0
            if (i == -1) {
560
0
                j = BN_num_bits_word((BN_ULONG)bl);
561
0
            }
562
0
            j = 1 << (j - 1);
563
0
            assert(j <= al || j <= bl);
564
0
            k = j + j;
565
0
            t = BN_CTX_get(ctx);
566
0
            if (t == NULL)
567
0
                goto err;
568
0
            if (al > j || bl > j) {
569
0
                if (bn_wexpand(t, k * 4) == NULL)
570
0
                    goto err;
571
0
                if (bn_wexpand(rr, k * 4) == NULL)
572
0
                    goto err;
573
0
                bn_mul_part_recursive(rr->d, a->d, b->d,
574
0
                    j, al - j, bl - j, t->d);
575
0
            } else { /* al <= j || bl <= j */
576
577
0
                if (bn_wexpand(t, k * 2) == NULL)
578
0
                    goto err;
579
0
                if (bn_wexpand(rr, k * 2) == NULL)
580
0
                    goto err;
581
0
                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
582
0
            }
583
0
            rr->top = top;
584
0
            goto end;
585
0
        }
586
0
    }
587
0
#endif /* OPENSSL_SMALL_FOOTPRINT */
588
0
    if (bn_wexpand(rr, top) == NULL)
589
0
        goto err;
590
0
    rr->top = top;
591
0
    bn_mul_normal(rr->d, a->d, al, b->d, bl);
592
593
0
#if !defined(OPENSSL_SMALL_FOOTPRINT)
594
0
end:
595
0
#endif
596
0
    rr->neg = a->neg ^ b->neg;
597
0
    rr->flags |= BN_FLG_FIXED_TOP;
598
0
    if (r != rr && BN_copy(r, rr) == NULL)
599
0
        goto err;
600
601
0
    ret = 1;
602
0
err:
603
0
    bn_check_top(r);
604
0
    BN_CTX_end(ctx);
605
0
    return ret;
606
0
}
607
608
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
609
0
{
610
0
    BN_ULONG *rr;
611
612
0
    if (na < nb) {
613
0
        int itmp;
614
0
        BN_ULONG *ltmp;
615
616
0
        itmp = na;
617
0
        na = nb;
618
0
        nb = itmp;
619
0
        ltmp = a;
620
0
        a = b;
621
0
        b = ltmp;
622
0
    }
623
0
    rr = &(r[na]);
624
0
    if (nb <= 0) {
625
0
        (void)bn_mul_words(r, a, na, 0);
626
0
        return;
627
0
    } else
628
0
        rr[0] = bn_mul_words(r, a, na, b[0]);
629
630
0
    for (;;) {
631
0
        if (--nb <= 0)
632
0
            return;
633
0
        rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
634
0
        if (--nb <= 0)
635
0
            return;
636
0
        rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
637
0
        if (--nb <= 0)
638
0
            return;
639
0
        rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
640
0
        if (--nb <= 0)
641
0
            return;
642
0
        rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
643
0
        rr += 4;
644
0
        r += 4;
645
0
        b += 4;
646
0
    }
647
0
}
648
649
void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
650
0
{
651
0
    bn_mul_words(r, a, n, b[0]);
652
653
0
    for (;;) {
654
0
        if (--n <= 0)
655
0
            return;
656
0
        bn_mul_add_words(&(r[1]), a, n, b[1]);
657
0
        if (--n <= 0)
658
0
            return;
659
0
        bn_mul_add_words(&(r[2]), a, n, b[2]);
660
0
        if (--n <= 0)
661
0
            return;
662
0
        bn_mul_add_words(&(r[3]), a, n, b[3]);
663
0
        if (--n <= 0)
664
0
            return;
665
0
        bn_mul_add_words(&(r[4]), a, n, b[4]);
666
0
        r += 4;
667
0
        b += 4;
668
0
    }
669
0
}