Coverage Report

Created: 2022-08-24 06:31

/src/libressl/crypto/bn/bn_mul.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: bn_mul.c,v 1.20 2015/02/09 15:49:22 jsing Exp $ */
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 <assert.h>
65
#include <stdio.h>
66
#include <string.h>
67
68
#include <openssl/opensslconf.h>
69
70
#include "bn_lcl.h"
71
72
#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
73
/* Here follows specialised variants of bn_add_words() and
74
   bn_sub_words().  They have the property performing operations on
75
   arrays of different sizes.  The sizes of those arrays is expressed through
76
   cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
77
   which is the delta between the two lengths, calculated as len(a)-len(b).
78
   All lengths are the number of BN_ULONGs...  For the operations that require
79
   a result array as parameter, it must have the length cl+abs(dl).
80
   These functions should probably end up in bn_asm.c as soon as there are
81
   assembler counterparts for the systems that use assembler files.  */
82
83
BN_ULONG
84
bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int cl,
85
    int dl)
86
519k
{
87
519k
  BN_ULONG c, t;
88
89
519k
  assert(cl >= 0);
90
519k
  c = bn_sub_words(r, a, b, cl);
91
92
519k
  if (dl == 0)
93
302k
    return c;
94
95
216k
  r += cl;
96
216k
  a += cl;
97
216k
  b += cl;
98
99
216k
  if (dl < 0) {
100
#ifdef BN_COUNT
101
    fprintf(stderr,
102
        "  bn_sub_part_words %d + %d (dl < 0, c = %d)\n",
103
        cl, dl, c);
104
#endif
105
48.8k
    for (;;) {
106
48.8k
      t = b[0];
107
48.8k
      r[0] = (0 - t - c) & BN_MASK2;
108
48.8k
      if (t != 0)
109
0
        c = 1;
110
48.8k
      if (++dl >= 0)
111
22.6k
        break;
112
113
26.2k
      t = b[1];
114
26.2k
      r[1] = (0 - t - c) & BN_MASK2;
115
26.2k
      if (t != 0)
116
0
        c = 1;
117
26.2k
      if (++dl >= 0)
118
957
        break;
119
120
25.2k
      t = b[2];
121
25.2k
      r[2] = (0 - t - c) & BN_MASK2;
122
25.2k
      if (t != 0)
123
0
        c = 1;
124
25.2k
      if (++dl >= 0)
125
695
        break;
126
127
24.5k
      t = b[3];
128
24.5k
      r[3] = (0 - t - c) & BN_MASK2;
129
24.5k
      if (t != 0)
130
0
        c = 1;
131
24.5k
      if (++dl >= 0)
132
159
        break;
133
134
24.4k
      b += 4;
135
24.4k
      r += 4;
136
24.4k
    }
137
192k
  } else {
138
192k
    int save_dl = dl;
139
#ifdef BN_COUNT
140
    fprintf(stderr,
141
        "  bn_sub_part_words %d + %d (dl > 0, c = %d)\n",
142
        cl, dl, c);
143
#endif
144
232k
    while (c) {
145
45.3k
      t = a[0];
146
45.3k
      r[0] = (t - c) & BN_MASK2;
147
45.3k
      if (t != 0)
148
14.0k
        c = 0;
149
45.3k
      if (--dl <= 0)
150
3.76k
        break;
151
152
41.5k
      t = a[1];
153
41.5k
      r[1] = (t - c) & BN_MASK2;
154
41.5k
      if (t != 0)
155
13.8k
        c = 0;
156
41.5k
      if (--dl <= 0)
157
489
        break;
158
159
41.0k
      t = a[2];
160
41.0k
      r[2] = (t - c) & BN_MASK2;
161
41.0k
      if (t != 0)
162
22.6k
        c = 0;
163
41.0k
      if (--dl <= 0)
164
468
        break;
165
166
40.6k
      t = a[3];
167
40.6k
      r[3] = (t - c) & BN_MASK2;
168
40.6k
      if (t != 0)
169
24.7k
        c = 0;
170
40.6k
      if (--dl <= 0)
171
382
        break;
172
173
40.2k
      save_dl = dl;
174
40.2k
      a += 4;
175
40.2k
      r += 4;
176
40.2k
    }
177
192k
    if (dl > 0) {
178
#ifdef BN_COUNT
179
      fprintf(stderr,
180
          "  bn_sub_part_words %d + %d (dl > 0, c == 0)\n",
181
          cl, dl);
182
#endif
183
187k
      if (save_dl > dl) {
184
0
        switch (save_dl - dl) {
185
0
        case 1:
186
0
          r[1] = a[1];
187
0
          if (--dl <= 0)
188
0
            break;
189
0
        case 2:
190
0
          r[2] = a[2];
191
0
          if (--dl <= 0)
192
0
            break;
193
0
        case 3:
194
0
          r[3] = a[3];
195
0
          if (--dl <= 0)
196
0
            break;
197
0
        }
198
0
        a += 4;
199
0
        r += 4;
200
0
      }
201
187k
    }
202
192k
    if (dl > 0) {
203
#ifdef BN_COUNT
204
      fprintf(stderr,
205
          "  bn_sub_part_words %d + %d (dl > 0, copy)\n",
206
          cl, dl);
207
#endif
208
413k
      for (;;) {
209
413k
        r[0] = a[0];
210
413k
        if (--dl <= 0)
211
140k
          break;
212
273k
        r[1] = a[1];
213
273k
        if (--dl <= 0)
214
6.96k
          break;
215
266k
        r[2] = a[2];
216
266k
        if (--dl <= 0)
217
27.1k
          break;
218
239k
        r[3] = a[3];
219
239k
        if (--dl <= 0)
220
12.6k
          break;
221
222
226k
        a += 4;
223
226k
        r += 4;
224
226k
      }
225
187k
    }
226
192k
  }
227
216k
  return c;
228
216k
}
229
#endif
230
231
BN_ULONG
232
bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int cl,
233
    int dl)
234
0
{
235
0
  BN_ULONG c, l, t;
236
237
0
  assert(cl >= 0);
238
0
  c = bn_add_words(r, a, b, cl);
239
240
0
  if (dl == 0)
241
0
    return c;
242
243
0
  r += cl;
244
0
  a += cl;
245
0
  b += cl;
246
247
0
  if (dl < 0) {
248
0
    int save_dl = dl;
249
#ifdef BN_COUNT
250
    fprintf(stderr,
251
        "  bn_add_part_words %d + %d (dl < 0, c = %d)\n",
252
        cl, dl, c);
253
#endif
254
0
    while (c) {
255
0
      l = (c + b[0]) & BN_MASK2;
256
0
      c = (l < c);
257
0
      r[0] = l;
258
0
      if (++dl >= 0)
259
0
        break;
260
261
0
      l = (c + b[1]) & BN_MASK2;
262
0
      c = (l < c);
263
0
      r[1] = l;
264
0
      if (++dl >= 0)
265
0
        break;
266
267
0
      l = (c + b[2]) & BN_MASK2;
268
0
      c = (l < c);
269
0
      r[2] = l;
270
0
      if (++dl >= 0)
271
0
        break;
272
273
0
      l = (c + b[3]) & BN_MASK2;
274
0
      c = (l < c);
275
0
      r[3] = l;
276
0
      if (++dl >= 0)
277
0
        break;
278
279
0
      save_dl = dl;
280
0
      b += 4;
281
0
      r += 4;
282
0
    }
283
0
    if (dl < 0) {
284
#ifdef BN_COUNT
285
      fprintf(stderr,
286
          "  bn_add_part_words %d + %d (dl < 0, c == 0)\n",
287
          cl, dl);
288
#endif
289
0
      if (save_dl < dl) {
290
0
        switch (dl - save_dl) {
291
0
        case 1:
292
0
          r[1] = b[1];
293
0
          if (++dl >= 0)
294
0
            break;
295
0
        case 2:
296
0
          r[2] = b[2];
297
0
          if (++dl >= 0)
298
0
            break;
299
0
        case 3:
300
0
          r[3] = b[3];
301
0
          if (++dl >= 0)
302
0
            break;
303
0
        }
304
0
        b += 4;
305
0
        r += 4;
306
0
      }
307
0
    }
308
0
    if (dl < 0) {
309
#ifdef BN_COUNT
310
      fprintf(stderr,
311
          "  bn_add_part_words %d + %d (dl < 0, copy)\n",
312
          cl, dl);
313
#endif
314
0
      for (;;) {
315
0
        r[0] = b[0];
316
0
        if (++dl >= 0)
317
0
          break;
318
0
        r[1] = b[1];
319
0
        if (++dl >= 0)
320
0
          break;
321
0
        r[2] = b[2];
322
0
        if (++dl >= 0)
323
0
          break;
324
0
        r[3] = b[3];
325
0
        if (++dl >= 0)
326
0
          break;
327
328
0
        b += 4;
329
0
        r += 4;
330
0
      }
331
0
    }
332
0
  } else {
333
0
    int save_dl = dl;
334
#ifdef BN_COUNT
335
    fprintf(stderr,
336
        "  bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
337
#endif
338
0
    while (c) {
339
0
      t = (a[0] + c) & BN_MASK2;
340
0
      c = (t < c);
341
0
      r[0] = t;
342
0
      if (--dl <= 0)
343
0
        break;
344
345
0
      t = (a[1] + c) & BN_MASK2;
346
0
      c = (t < c);
347
0
      r[1] = t;
348
0
      if (--dl <= 0)
349
0
        break;
350
351
0
      t = (a[2] + c) & BN_MASK2;
352
0
      c = (t < c);
353
0
      r[2] = t;
354
0
      if (--dl <= 0)
355
0
        break;
356
357
0
      t = (a[3] + c) & BN_MASK2;
358
0
      c = (t < c);
359
0
      r[3] = t;
360
0
      if (--dl <= 0)
361
0
        break;
362
363
0
      save_dl = dl;
364
0
      a += 4;
365
0
      r += 4;
366
0
    }
367
#ifdef BN_COUNT
368
    fprintf(stderr,
369
        "  bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
370
#endif
371
0
    if (dl > 0) {
372
0
      if (save_dl > dl) {
373
0
        switch (save_dl - dl) {
374
0
        case 1:
375
0
          r[1] = a[1];
376
0
          if (--dl <= 0)
377
0
            break;
378
0
        case 2:
379
0
          r[2] = a[2];
380
0
          if (--dl <= 0)
381
0
            break;
382
0
        case 3:
383
0
          r[3] = a[3];
384
0
          if (--dl <= 0)
385
0
            break;
386
0
        }
387
0
        a += 4;
388
0
        r += 4;
389
0
      }
390
0
    }
391
0
    if (dl > 0) {
392
#ifdef BN_COUNT
393
      fprintf(stderr,
394
          "  bn_add_part_words %d + %d (dl > 0, copy)\n",
395
          cl, dl);
396
#endif
397
0
      for (;;) {
398
0
        r[0] = a[0];
399
0
        if (--dl <= 0)
400
0
          break;
401
0
        r[1] = a[1];
402
0
        if (--dl <= 0)
403
0
          break;
404
0
        r[2] = a[2];
405
0
        if (--dl <= 0)
406
0
          break;
407
0
        r[3] = a[3];
408
0
        if (--dl <= 0)
409
0
          break;
410
411
0
        a += 4;
412
0
        r += 4;
413
0
      }
414
0
    }
415
0
  }
416
0
  return c;
417
0
}
418
419
#ifdef BN_RECURSION
420
/* Karatsuba recursive multiplication algorithm
421
 * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
422
423
/* r is 2*n2 words in size,
424
 * a and b are both n2 words in size.
425
 * n2 must be a power of 2.
426
 * We multiply and return the result.
427
 * t must be 2*n2 words in size
428
 * We calculate
429
 * a[0]*b[0]
430
 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
431
 * a[1]*b[1]
432
 */
433
/* dnX may not be positive, but n2/2+dnX has to be */
434
void
435
bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, int dna,
436
    int dnb, BN_ULONG *t)
437
161k
{
438
161k
  int n = n2 / 2, c1, c2;
439
161k
  int tna = n + dna, tnb = n + dnb;
440
161k
  unsigned int neg, zero;
441
161k
  BN_ULONG ln, lo, *p;
442
443
# ifdef BN_COUNT
444
  fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
445
# endif
446
161k
# ifdef BN_MUL_COMBA
447
#  if 0
448
  if (n2 == 4) {
449
    bn_mul_comba4(r, a, b);
450
    return;
451
  }
452
#  endif
453
  /* Only call bn_mul_comba 8 if n2 == 8 and the
454
   * two arrays are complete [steve]
455
   */
456
161k
  if (n2 == 8 && dna == 0 && dnb == 0) {
457
1.68k
    bn_mul_comba8(r, a, b);
458
1.68k
    return;
459
1.68k
  }
460
159k
# endif /* BN_MUL_COMBA */
461
  /* Else do normal multiply */
462
159k
  if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
463
765
    bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
464
765
    if ((dna + dnb) < 0)
465
765
      memset(&r[2*n2 + dna + dnb], 0,
466
765
          sizeof(BN_ULONG) * -(dna + dnb));
467
765
    return;
468
765
  }
469
  /* r=(a[0]-a[1])*(b[1]-b[0]) */
470
158k
  c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
471
158k
  c2 = bn_cmp_part_words(&(b[n]), b,tnb, tnb - n);
472
158k
  zero = neg = 0;
473
158k
  switch (c1 * 3 + c2) {
474
39.2k
  case -4:
475
39.2k
    bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
476
39.2k
    bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
477
39.2k
    break;
478
677
  case -3:
479
677
    zero = 1;
480
677
    break;
481
35.7k
  case -2:
482
35.7k
    bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
483
35.7k
    bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
484
35.7k
    neg = 1;
485
35.7k
    break;
486
2.15k
  case -1:
487
2.89k
  case 0:
488
5.71k
  case 1:
489
5.71k
    zero = 1;
490
5.71k
    break;
491
36.6k
  case 2:
492
36.6k
    bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
493
36.6k
    bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
494
36.6k
    neg = 1;
495
36.6k
    break;
496
520
  case 3:
497
520
    zero = 1;
498
520
    break;
499
40.0k
  case 4:
500
40.0k
    bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
501
40.0k
    bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
502
40.0k
    break;
503
158k
  }
504
505
158k
# ifdef BN_MUL_COMBA
506
158k
  if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
507
                 extra args to do this well */
508
0
  {
509
0
    if (!zero)
510
0
      bn_mul_comba4(&(t[n2]), t, &(t[n]));
511
0
    else
512
0
      memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
513
514
0
    bn_mul_comba4(r, a, b);
515
0
    bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
516
158k
  } else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
517
                take extra args to do this
518
                well */
519
151k
  {
520
151k
    if (!zero)
521
145k
      bn_mul_comba8(&(t[n2]), t, &(t[n]));
522
6.65k
    else
523
6.65k
      memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
524
525
151k
    bn_mul_comba8(r, a, b);
526
151k
    bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
527
151k
  } else
528
6.77k
# endif /* BN_MUL_COMBA */
529
6.77k
  {
530
6.77k
    p = &(t[n2 * 2]);
531
6.77k
    if (!zero)
532
6.52k
      bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
533
250
    else
534
250
      memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
535
6.77k
    bn_mul_recursive(r, a, b, n, 0, 0, p);
536
6.77k
    bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
537
6.77k
  }
538
539
  /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
540
   * r[10] holds (a[0]*b[0])
541
   * r[32] holds (b[1]*b[1])
542
   */
543
544
158k
  c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
545
546
158k
  if (neg) /* if t[32] is negative */
547
72.4k
  {
548
72.4k
    c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
549
86.2k
  } else {
550
    /* Might have a carry */
551
86.2k
    c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
552
86.2k
  }
553
554
  /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
555
   * r[10] holds (a[0]*b[0])
556
   * r[32] holds (b[1]*b[1])
557
   * c1 holds the carry bits
558
   */
559
158k
  c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
560
158k
  if (c1) {
561
51.3k
    p = &(r[n + n2]);
562
51.3k
    lo= *p;
563
51.3k
    ln = (lo + c1) & BN_MASK2;
564
51.3k
    *p = ln;
565
566
    /* The overflow will stop before we over write
567
     * words we should not overwrite */
568
51.3k
    if (ln < (BN_ULONG)c1) {
569
7.66k
      do {
570
7.66k
        p++;
571
7.66k
        lo= *p;
572
7.66k
        ln = (lo + 1) & BN_MASK2;
573
7.66k
        *p = ln;
574
7.66k
      } while (ln == 0);
575
2.61k
    }
576
51.3k
  }
577
158k
}
578
579
/* n+tn is the word length
580
 * t needs to be n*4 is size, as does r */
581
/* tnX may not be negative but less than n */
582
void
583
bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, int tna,
584
    int tnb, BN_ULONG *t)
585
107k
{
586
107k
  int i, j, n2 = n * 2;
587
107k
  int c1, c2, neg;
588
107k
  BN_ULONG ln, lo, *p;
589
590
# ifdef BN_COUNT
591
  fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
592
      n, tna, n, tnb);
593
# endif
594
107k
  if (n < 8) {
595
0
    bn_mul_normal(r, a, n + tna, b, n + tnb);
596
0
    return;
597
0
  }
598
599
  /* r=(a[0]-a[1])*(b[1]-b[0]) */
600
107k
  c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
601
107k
  c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
602
107k
  neg = 0;
603
107k
  switch (c1 * 3 + c2) {
604
15.9k
  case -4:
605
15.9k
    bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
606
15.9k
    bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
607
15.9k
    break;
608
100
  case -3:
609
    /* break; */
610
2.70k
  case -2:
611
2.70k
    bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
612
2.70k
    bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
613
2.70k
    neg = 1;
614
2.70k
    break;
615
1.15k
  case -1:
616
1.28k
  case 0:
617
1.38k
  case 1:
618
    /* break; */
619
86.0k
  case 2:
620
86.0k
    bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
621
86.0k
    bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
622
86.0k
    neg = 1;
623
86.0k
    break;
624
782
  case 3:
625
    /* break; */
626
3.02k
  case 4:
627
3.02k
    bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
628
3.02k
    bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
629
3.02k
    break;
630
107k
  }
631
    /* The zero case isn't yet implemented here. The speedup
632
       would probably be negligible. */
633
# if 0
634
  if (n == 4) {
635
    bn_mul_comba4(&(t[n2]), t, &(t[n]));
636
    bn_mul_comba4(r, a, b);
637
    bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
638
    memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2));
639
  } else
640
# endif
641
107k
    if (n == 8) {
642
44.1k
    bn_mul_comba8(&(t[n2]), t, &(t[n]));
643
44.1k
    bn_mul_comba8(r, a, b);
644
44.1k
    bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
645
44.1k
    memset(&(r[n2 + tna + tnb]), 0,
646
44.1k
        sizeof(BN_ULONG) * (n2 - tna - tnb));
647
63.6k
  } else {
648
63.6k
    p = &(t[n2*2]);
649
63.6k
    bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
650
63.6k
    bn_mul_recursive(r, a, b, n, 0, 0, p);
651
63.6k
    i = n / 2;
652
    /* If there is only a bottom half to the number,
653
     * just do it */
654
63.6k
    if (tna > tnb)
655
3.84k
      j = tna - i;
656
59.7k
    else
657
59.7k
      j = tnb - i;
658
63.6k
    if (j == 0) {
659
408
      bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
660
408
          i, tna - i, tnb - i, p);
661
408
      memset(&(r[n2 + i * 2]), 0,
662
408
          sizeof(BN_ULONG) * (n2 - i * 2));
663
408
    }
664
63.2k
    else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
665
44.1k
    {
666
44.1k
      bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
667
44.1k
          i, tna - i, tnb - i, p);
668
44.1k
      memset(&(r[n2 + tna + tnb]), 0,
669
44.1k
          sizeof(BN_ULONG) * (n2 - tna - tnb));
670
44.1k
    }
671
19.0k
    else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
672
19.0k
    {
673
19.0k
      memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2);
674
19.0k
      if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL &&
675
19.0k
          tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
676
19.0k
        bn_mul_normal(&(r[n2]), &(a[n]), tna,
677
19.0k
            &(b[n]), tnb);
678
19.0k
      } else {
679
0
        for (;;) {
680
0
          i /= 2;
681
          /* these simplified conditions work
682
           * exclusively because difference
683
           * between tna and tnb is 1 or 0 */
684
0
          if (i < tna || i < tnb) {
685
0
            bn_mul_part_recursive(&(r[n2]),
686
0
                &(a[n]), &(b[n]), i,
687
0
                tna - i, tnb - i, p);
688
0
            break;
689
0
          } else if (i == tna || i == tnb) {
690
0
            bn_mul_recursive(&(r[n2]),
691
0
                &(a[n]), &(b[n]), i,
692
0
                tna - i, tnb - i, p);
693
0
            break;
694
0
          }
695
0
        }
696
0
      }
697
19.0k
    }
698
63.6k
  }
699
700
  /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
701
   * r[10] holds (a[0]*b[0])
702
   * r[32] holds (b[1]*b[1])
703
   */
704
705
107k
  c1 = (int)(bn_add_words(t, r,&(r[n2]), n2));
706
707
107k
  if (neg) /* if t[32] is negative */
708
88.7k
  {
709
88.7k
    c1 -= (int)(bn_sub_words(&(t[n2]), t,&(t[n2]), n2));
710
88.7k
  } else {
711
    /* Might have a carry */
712
18.9k
    c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
713
18.9k
  }
714
715
  /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
716
   * r[10] holds (a[0]*b[0])
717
   * r[32] holds (b[1]*b[1])
718
   * c1 holds the carry bits
719
   */
720
107k
  c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
721
107k
  if (c1) {
722
1.04k
    p = &(r[n + n2]);
723
1.04k
    lo= *p;
724
1.04k
    ln = (lo + c1)&BN_MASK2;
725
1.04k
    *p = ln;
726
727
    /* The overflow will stop before we over write
728
     * words we should not overwrite */
729
1.04k
    if (ln < (BN_ULONG)c1) {
730
2.50k
      do {
731
2.50k
        p++;
732
2.50k
        lo= *p;
733
2.50k
        ln = (lo + 1) & BN_MASK2;
734
2.50k
        *p = ln;
735
2.50k
      } while (ln == 0);
736
749
    }
737
1.04k
  }
738
107k
}
739
740
/* a and b must be the same size, which is n2.
741
 * r needs to be n2 words and t needs to be n2*2
742
 */
743
void
744
bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, BN_ULONG *t)
745
0
{
746
0
  int n = n2 / 2;
747
748
# ifdef BN_COUNT
749
  fprintf(stderr, " bn_mul_low_recursive %d * %d\n",n2,n2);
750
# endif
751
752
0
  bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
753
0
  if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
754
0
    bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
755
0
    bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
756
0
    bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
757
0
    bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
758
0
  } else {
759
0
    bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
760
0
    bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
761
0
    bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
762
0
    bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
763
0
  }
764
0
}
765
766
/* a and b must be the same size, which is n2.
767
 * r needs to be n2 words and t needs to be n2*2
768
 * l is the low words of the output.
769
 * t needs to be n2*3
770
 */
771
void
772
bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
773
    BN_ULONG *t)
774
0
{
775
0
  int i, n;
776
0
  int c1, c2;
777
0
  int neg, oneg, zero;
778
0
  BN_ULONG ll, lc, *lp, *mp;
779
780
# ifdef BN_COUNT
781
  fprintf(stderr, " bn_mul_high %d * %d\n",n2,n2);
782
# endif
783
0
  n = n2 / 2;
784
785
  /* Calculate (al-ah)*(bh-bl) */
786
0
  neg = zero = 0;
787
0
  c1 = bn_cmp_words(&(a[0]), &(a[n]), n);
788
0
  c2 = bn_cmp_words(&(b[n]), &(b[0]), n);
789
0
  switch (c1 * 3 + c2) {
790
0
  case -4:
791
0
    bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
792
0
    bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
793
0
    break;
794
0
  case -3:
795
0
    zero = 1;
796
0
    break;
797
0
  case -2:
798
0
    bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
799
0
    bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
800
0
    neg = 1;
801
0
    break;
802
0
  case -1:
803
0
  case 0:
804
0
  case 1:
805
0
    zero = 1;
806
0
    break;
807
0
  case 2:
808
0
    bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
809
0
    bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
810
0
    neg = 1;
811
0
    break;
812
0
  case 3:
813
0
    zero = 1;
814
0
    break;
815
0
  case 4:
816
0
    bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
817
0
    bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
818
0
    break;
819
0
  }
820
821
0
  oneg = neg;
822
  /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
823
  /* r[10] = (a[1]*b[1]) */
824
0
# ifdef BN_MUL_COMBA
825
0
  if (n == 8) {
826
0
    bn_mul_comba8(&(t[0]), &(r[0]), &(r[n]));
827
0
    bn_mul_comba8(r, &(a[n]), &(b[n]));
828
0
  } else
829
0
# endif
830
0
  {
831
0
    bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2]));
832
0
    bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2]));
833
0
  }
834
835
  /* s0 == low(al*bl)
836
   * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
837
   * We know s0 and s1 so the only unknown is high(al*bl)
838
   * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
839
   * high(al*bl) == s1 - (r[0]+l[0]+t[0])
840
   */
841
0
  if (l != NULL) {
842
0
    lp = &(t[n2 + n]);
843
0
    c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n));
844
0
  } else {
845
0
    c1 = 0;
846
0
    lp = &(r[0]);
847
0
  }
848
849
0
  if (neg)
850
0
    neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n));
851
0
  else {
852
0
    bn_add_words(&(t[n2]), lp, &(t[0]), n);
853
0
    neg = 0;
854
0
  }
855
856
0
  if (l != NULL) {
857
0
    bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n);
858
0
  } else {
859
0
    lp = &(t[n2 + n]);
860
0
    mp = &(t[n2]);
861
0
    for (i = 0; i < n; i++)
862
0
      lp[i] = ((~mp[i]) + 1) & BN_MASK2;
863
0
  }
864
865
  /* s[0] = low(al*bl)
866
   * t[3] = high(al*bl)
867
   * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
868
   * r[10] = (a[1]*b[1])
869
   */
870
  /* R[10] = al*bl
871
   * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
872
   * R[32] = ah*bh
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
  {
900
0
    i = 0;
901
0
    if (c1 > 0) {
902
0
      lc = c1;
903
0
      do {
904
0
        ll = (r[i] + lc) & BN_MASK2;
905
0
        r[i++] = ll;
906
0
        lc = (lc > ll);
907
0
      } while (lc);
908
0
    } else {
909
0
      lc = -c1;
910
0
      do {
911
0
        ll = r[i];
912
0
        r[i++] = (ll - lc) & BN_MASK2;
913
0
        lc = (lc > ll);
914
0
      } while (lc);
915
0
    }
916
0
  }
917
0
  if (c2 != 0) /* Add starting at r[1] */
918
0
  {
919
0
    i = n;
920
0
    if (c2 > 0) {
921
0
      lc = c2;
922
0
      do {
923
0
        ll = (r[i] + lc) & BN_MASK2;
924
0
        r[i++] = ll;
925
0
        lc = (lc > ll);
926
0
      } while (lc);
927
0
    } else {
928
0
      lc = -c2;
929
0
      do {
930
0
        ll = r[i];
931
0
        r[i++] = (ll - lc) & BN_MASK2;
932
0
        lc = (lc > ll);
933
0
      } while (lc);
934
0
    }
935
0
  }
936
0
}
937
#endif /* BN_RECURSION */
938
939
int
940
BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
941
687k
{
942
687k
  int ret = 0;
943
687k
  int top, al, bl;
944
687k
  BIGNUM *rr;
945
687k
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
946
687k
  int i;
947
687k
#endif
948
687k
#ifdef BN_RECURSION
949
687k
  BIGNUM *t = NULL;
950
687k
  int j = 0, k;
951
687k
#endif
952
953
#ifdef BN_COUNT
954
  fprintf(stderr, "BN_mul %d * %d\n",a->top,b->top);
955
#endif
956
957
687k
  bn_check_top(a);
958
687k
  bn_check_top(b);
959
687k
  bn_check_top(r);
960
961
687k
  al = a->top;
962
687k
  bl = b->top;
963
964
687k
  if ((al == 0) || (bl == 0)) {
965
31.7k
    BN_zero(r);
966
31.7k
    return (1);
967
31.7k
  }
968
656k
  top = al + bl;
969
970
656k
  BN_CTX_start(ctx);
971
656k
  if ((r == a) || (r == b)) {
972
0
    if ((rr = BN_CTX_get(ctx)) == NULL)
973
0
      goto err;
974
0
  } else
975
656k
    rr = r;
976
656k
  rr->neg = a->neg ^ b->neg;
977
978
656k
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
979
656k
  i = al - bl;
980
656k
#endif
981
656k
#ifdef BN_MUL_COMBA
982
656k
  if (i == 0) {
983
# if 0
984
    if (al == 4) {
985
      if (bn_wexpand(rr, 8) == NULL)
986
        goto err;
987
      rr->top = 8;
988
      bn_mul_comba4(rr->d, a->d, b->d);
989
      goto end;
990
    }
991
# endif
992
270k
    if (al == 8) {
993
1.60k
      if (bn_wexpand(rr, 16) == NULL)
994
0
        goto err;
995
1.60k
      rr->top = 16;
996
1.60k
      bn_mul_comba8(rr->d, a->d, b->d);
997
1.60k
      goto end;
998
1.60k
    }
999
270k
  }
1000
654k
#endif /* BN_MUL_COMBA */
1001
654k
#ifdef BN_RECURSION
1002
654k
  if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
1003
86.4k
    if (i >= -1 && i <= 1) {
1004
      /* Find out the power of two lower or equal
1005
         to the longest of the two numbers */
1006
77.0k
      if (i >= 0) {
1007
66.1k
        j = BN_num_bits_word((BN_ULONG)al);
1008
66.1k
      }
1009
77.0k
      if (i == -1) {
1010
10.9k
        j = BN_num_bits_word((BN_ULONG)bl);
1011
10.9k
      }
1012
77.0k
      j = 1 << (j - 1);
1013
77.0k
      assert(j <= al || j <= bl);
1014
77.0k
      k = j + j;
1015
77.0k
      if ((t = BN_CTX_get(ctx)) == NULL)
1016
0
        goto err;
1017
77.0k
      if (al > j || bl > j) {
1018
63.6k
        if (bn_wexpand(t, k * 4) == NULL)
1019
0
          goto err;
1020
63.6k
        if (bn_wexpand(rr, k * 4) == NULL)
1021
0
          goto err;
1022
63.6k
        bn_mul_part_recursive(rr->d, a->d, b->d,
1023
63.6k
            j, al - j, bl - j, t->d);
1024
63.6k
      }
1025
13.4k
      else  /* al <= j || bl <= j */
1026
13.4k
      {
1027
13.4k
        if (bn_wexpand(t, k * 2) == NULL)
1028
0
          goto err;
1029
13.4k
        if (bn_wexpand(rr, k * 2) == NULL)
1030
0
          goto err;
1031
13.4k
        bn_mul_recursive(rr->d, a->d, b->d,
1032
13.4k
            j, al - j, bl - j, t->d);
1033
13.4k
      }
1034
77.0k
      rr->top = top;
1035
77.0k
      goto end;
1036
77.0k
    }
1037
#if 0
1038
    if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
1039
      BIGNUM *tmp_bn = (BIGNUM *)b;
1040
      if (bn_wexpand(tmp_bn, al) == NULL)
1041
        goto err;
1042
      tmp_bn->d[bl] = 0;
1043
      bl++;
1044
      i--;
1045
    } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
1046
      BIGNUM *tmp_bn = (BIGNUM *)a;
1047
      if (bn_wexpand(tmp_bn, bl) == NULL)
1048
        goto err;
1049
      tmp_bn->d[al] = 0;
1050
      al++;
1051
      i++;
1052
    }
1053
    if (i == 0) {
1054
      /* symmetric and > 4 */
1055
      /* 16 or larger */
1056
      j = BN_num_bits_word((BN_ULONG)al);
1057
      j = 1 << (j - 1);
1058
      k = j + j;
1059
      if ((t = BN_CTX_get(ctx)) == NULL)
1060
        goto err;
1061
      if (al == j) /* exact multiple */
1062
      {
1063
        if (bn_wexpand(t, k * 2) == NULL)
1064
          goto err;
1065
        if (bn_wexpand(rr, k * 2) == NULL)
1066
          goto err;
1067
        bn_mul_recursive(rr->d, a->d, b->d, al, t->d);
1068
      } else {
1069
        if (bn_wexpand(t, k * 4) == NULL)
1070
          goto err;
1071
        if (bn_wexpand(rr, k * 4) == NULL)
1072
          goto err;
1073
        bn_mul_part_recursive(rr->d, a->d, b->d,
1074
            al - j, j, t->d);
1075
      }
1076
      rr->top = top;
1077
      goto end;
1078
    }
1079
#endif
1080
86.4k
  }
1081
577k
#endif /* BN_RECURSION */
1082
577k
  if (bn_wexpand(rr, top) == NULL)
1083
0
    goto err;
1084
577k
  rr->top = top;
1085
577k
  bn_mul_normal(rr->d, a->d, al, b->d, bl);
1086
1087
577k
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
1088
656k
end:
1089
656k
#endif
1090
656k
  bn_correct_top(rr);
1091
656k
  if (r != rr)
1092
0
    BN_copy(r, rr);
1093
656k
  ret = 1;
1094
656k
err:
1095
656k
  bn_check_top(r);
1096
656k
  BN_CTX_end(ctx);
1097
656k
  return (ret);
1098
656k
}
1099
1100
void
1101
bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
1102
641k
{
1103
641k
  BN_ULONG *rr;
1104
1105
#ifdef BN_COUNT
1106
  fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb);
1107
#endif
1108
1109
641k
  if (na < nb) {
1110
309k
    int itmp;
1111
309k
    BN_ULONG *ltmp;
1112
1113
309k
    itmp = na;
1114
309k
    na = nb;
1115
309k
    nb = itmp;
1116
309k
    ltmp = a;
1117
309k
    a = b;
1118
309k
    b = ltmp;
1119
1120
309k
  }
1121
641k
  rr = &(r[na]);
1122
641k
  if (nb <= 0) {
1123
12.1k
    (void)bn_mul_words(r, a, na, 0);
1124
12.1k
    return;
1125
12.1k
  } else
1126
629k
    rr[0] = bn_mul_words(r, a, na, b[0]);
1127
1128
701k
  for (;;) {
1129
701k
    if (--nb <= 0)
1130
435k
      return;
1131
265k
    rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
1132
265k
    if (--nb <= 0)
1133
18.9k
      return;
1134
246k
    rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
1135
246k
    if (--nb <= 0)
1136
88.2k
      return;
1137
158k
    rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
1138
158k
    if (--nb <= 0)
1139
86.2k
      return;
1140
71.9k
    rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
1141
71.9k
    rr += 4;
1142
71.9k
    r += 4;
1143
71.9k
    b += 4;
1144
71.9k
  }
1145
629k
}
1146
1147
void
1148
bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
1149
0
{
1150
#ifdef BN_COUNT
1151
  fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n);
1152
#endif
1153
0
  bn_mul_words(r, a, n, b[0]);
1154
1155
0
  for (;;) {
1156
0
    if (--n <= 0)
1157
0
      return;
1158
0
    bn_mul_add_words(&(r[1]), a, n, b[1]);
1159
0
    if (--n <= 0)
1160
0
      return;
1161
0
    bn_mul_add_words(&(r[2]), a, n, b[2]);
1162
0
    if (--n <= 0)
1163
0
      return;
1164
0
    bn_mul_add_words(&(r[3]), a, n, b[3]);
1165
0
    if (--n <= 0)
1166
0
      return;
1167
0
    bn_mul_add_words(&(r[4]), a, n, b[4]);
1168
0
    r += 4;
1169
0
    b += 4;
1170
0
  }
1171
0
}