6 /* r is 2*n2 words in size,
7 * a and b are both n2 words in size.
8 * n2 must be a power of 2.
9 * We multiply and return the result.
10 * t must be 2*n2 words in size
13 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
16 void bn_mul_recursive(r,a,b,n2,t)
26 printf(" bn_mul_recursive %d * %d\n",n2,n2);
33 bn_mul_normal(r,a,n2,b,n2);
37 if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
39 /* This should not happen */
41 bn_mul_normal(r,a,n2,b,n2);
44 /* r=(a[0]-a[1])*(b[1]-b[0]) */
45 c1=bn_cmp_words(a,&(a[n]),n);
46 c2=bn_cmp_words(&(b[n]),b,n);
51 bn_sub_words(t, &(a[n]),a, n); /* - */
52 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
58 bn_sub_words(t, &(a[n]),a, n); /* - */
59 bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */
68 bn_sub_words(t, a, &(a[n]),n); /* + */
69 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
76 bn_sub_words(t, a, &(a[n]),n);
77 bn_sub_words(&(t[n]),&(b[n]),b, n);
84 bn_mul_comba8(&(t[n2]),t,&(t[n]));
86 memset(&(t[n2]),0,8*sizeof(BN_ULONG));
89 bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
95 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
97 memset(&(t[n2]),0,n*sizeof(BN_ULONG));
98 bn_mul_recursive(r,a,b,n,p);
99 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p);
102 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
103 * r[10] holds (a[0]*b[0])
104 * r[32] holds (b[1]*b[1])
107 c1=bn_add_words(t,r,&(r[n2]),n2);
109 if (neg) /* if t[32] is negative */
111 c1-=bn_sub_words(&(t[n2]),t,&(t[n2]),n2);
115 /* Might have a carry */
116 c1+=bn_add_words(&(t[n2]),&(t[n2]),t,n2);
119 /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
120 * r[10] holds (a[0]*b[0])
121 * r[32] holds (b[1]*b[1])
122 * c1 holds the carry bits
124 c1+=bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2);
132 /* The overflow will stop before we over write
133 * words we should not overwrite */
146 /* n+tn is the word length
147 * t needs to be n*4 is size, as does r */
148 void bn_mul_part_recursive(r,a,b,tn,n,t)
158 printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n);
163 bn_mul_normal(r,a,i,b,i);
167 /* r=(a[0]-a[1])*(b[1]-b[0]) */
168 bn_sub_words(t, a, &(a[n]),n); /* + */
169 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
173 bn_mul_comba8(&(t[n2]),t,&(t[n]));
174 bn_mul_comba8(r,a,b);
175 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
176 memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
181 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
182 bn_mul_recursive(r,a,b,n,p);
184 /* If there is only a bottom half to the number,
189 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p);
190 memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
192 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
194 bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
196 memset(&(r[n2+tn*2]),0,
197 sizeof(BN_ULONG)*(n2-tn*2));
199 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
201 memset(&(r[n2]),0,sizeof(BN_ULONG)*(tn*2));
207 bn_mul_part_recursive(&(r[n2]),
214 bn_mul_recursive(&(r[n2]),
223 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
224 * r[10] holds (a[0]*b[0])
225 * r[32] holds (b[1]*b[1])
228 c1=bn_add_words(t,r,&(r[n2]),n2);
229 c1-=bn_sub_words(&(t[n2]),t,&(t[n2]),n2);
231 /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
232 * r[10] holds (a[0]*b[0])
233 * r[32] holds (b[1]*b[1])
234 * c1 holds the carry bits
236 c1+=bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2);
244 /* The overflow will stop before we over write
245 * words we should not overwrite */
258 /* r is 2*n words in size,
259 * a and b are both n words in size.
260 * n must be a power of 2.
261 * We multiply and return the result.
262 * t must be 2*n words in size
265 * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
268 void bn_sqr_recursive(r,a,n2,t)
278 printf(" bn_sqr_recursive %d * %d\n",n2,n2);
290 if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
292 bn_sqr_normal(r,a,n2,t);
296 /* r=(a[0]-a[1])*(a[1]-a[0]) */
297 c1=bn_cmp_words(a,&(a[n]),n);
300 bn_sub_words(t,a,&(a[n]),n);
302 bn_sub_words(t,&(a[n]),a,n);
306 /* The result will always be negative unless it is zero */
311 bn_sqr_comba8(&(t[n2]),t);
313 memset(&(t[n2]),0,8*sizeof(BN_ULONG));
316 bn_sqr_comba8(&(r[n2]),&(a[n]));
322 bn_sqr_recursive(&(t[n2]),t,n,p);
324 memset(&(t[n2]),0,n*sizeof(BN_ULONG));
325 bn_sqr_recursive(r,a,n,p);
326 bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
329 /* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
330 * r[10] holds (a[0]*b[0])
331 * r[32] holds (b[1]*b[1])
334 c1=bn_add_words(t,r,&(r[n2]),n2);
336 /* t[32] is negative */
337 c1-=bn_sub_words(&(t[n2]),t,&(t[n2]),n2);
339 /* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
340 * r[10] holds (a[0]*a[0])
341 * r[32] holds (a[1]*a[1])
342 * c1 holds the carry bits
344 c1+=bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2);
352 /* The overflow will stop before we over write
353 * words we should not overwrite */
367 /* a and b must be the same size, which is n2.
368 * r needs to be n2 words and t needs to be n2*2
370 void bn_mul_low_recursive(r,a,b,n2,t)
378 printf(" bn_mul_low_recursive %d * %d\n",n2,n2);
381 bn_mul_recursive(r,a,b,n,&(t[0]));
382 if (n > BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
384 bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
385 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
386 bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
387 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
391 bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
392 bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
393 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
394 bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
398 /* a and b must be the same size, which is n2.
399 * r needs to be n2 words and t needs to be n2*2
400 * l is the low words of the output.
403 void bn_mul_high(r,a,b,l,n2,t)
404 BN_ULONG *r,*a,*b,*l;
410 BN_ULONG ll,lc,*lp,*mp;
413 printf(" bn_mul_high %d * %d\n",n2,n2);
417 /* Calculate (al-ah)*(bh-bl) */
419 c1=bn_cmp_words(&(a[0]),&(a[n]),n);
420 c2=bn_cmp_words(&(b[n]),&(b[0]),n);
424 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
425 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
431 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
432 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
441 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
442 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
449 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
450 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
455 /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
456 bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2]));
457 /* r[10] = (a[1]*b[1]) */
458 bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2]));
461 * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
462 * We know s0 and s1 so the only unknown is high(al*bl)
463 * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
464 * high(al*bl) == s1 - (r[0]+l[0]+t[0])
469 c1=bn_add_words(lp,&(r[0]),&(l[0]),n);
478 neg=bn_sub_words(&(t[n2]),lp,&(t[0]),n);
481 bn_add_words(&(t[n2]),lp,&(t[0]),n);
487 bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
494 lp[i]=((~mp[i])+1)&BN_MASK2;
499 * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
500 * r[10] = (a[1]*b[1])
503 * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
506 /* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
507 * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
508 * R[3]=r[1]+(carry/borrow)
513 c1= bn_add_words(lp,&(t[n2+n]),&(l[0]),n);
520 c1+=bn_add_words(&(t[n2]),lp, &(r[0]),n);
522 c1-=bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n);
524 c1+=bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n);
526 c2 =bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n);
527 c2+=bn_add_words(&(r[0]),&(r[0]),&(r[n]),n);
529 c2-=bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n);
531 c2+=bn_add_words(&(r[0]),&(r[0]),&(t[n]),n);
533 if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
540 ll=(r[i]+lc)&BN_MASK2;
550 r[i++]=(ll-lc)&BN_MASK2;
555 if (c2 != 0) /* Add starting at r[1] */
562 ll=(r[i]+lc)&BN_MASK2;
572 r[i++]=(ll-lc)&BN_MASK2;