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