1 /* crypto/bn/wei_mulw.c */
8 BN_ULONG bn_add_word(BN_ULONG *a,BN_ULONG c,int num);
9 BN_ULONG bn_add_words(BN_ULONG *ret,BN_ULONG *a,BN_ULONG *b,int num);
10 BN_ULONG bn_sub_words(BN_ULONG *ret,BN_ULONG *a,BN_ULONG *b,int num);
12 void BN_mul_4words(BN_ULONG *ret,BN_ULONG a0,BN_ULONG a1,
13 BN_ULONG b0,BN_ULONG b1);
20 fprintf(stdout,"%02X",a[n]);
21 fprintf(stdout,"%s",s);
25 BN_ULONG bn_add_word(a,w,num)
33 { BN_ULONG *aa=a; int i; for (i=num; i>0; i--) fprintf(stdout,"%02X",aa[i-1]);
34 fprintf(stdout," + %X - ",w); i=num;
42 if (w && --num) goto loop;
45 for (; i>0; i--) fprintf(stdout,"%02X",aa[i-1]);
53 BN_ULONG bn_add_words(r,a,b,num)
66 for (i=0; i<num; i+=2)
68 t=(BN_ULLONG)a[i]+b[i]+c;
70 t=(BN_ULLONG) H(t)+a[i+1]+b[i+1];
85 c=(t2 >= ((~t1)&BN_MASK2));
86 (*r++)=(t1+t2+1)&BN_MASK2;
99 BN_ULONG bn_sub_words(r,a,b,num)
105 #if defined(BN_LLONG)
112 for (i=0; i<num; i+=2)
114 t=(BN_ULLONG)a[i]-b[i]-c;
116 t=(BN_ULLONG)a[i+1]-b[i+1]-(0-H(t))&BN_MASK2;
146 /* ret[3,2,1,0] = a1,a0 * b1,b0 */
147 void BN_mul_4words(ret,a0,a1,b0,b1)
149 BN_ULONG a0,a1,b0,b1;
152 BN_ULLONG fix,a0b0,a1b1,tmp;
180 a0b0=(BN_ULLONG)a0*b0;
183 a1b1=(BN_ULLONG)a1*b1;
184 tmp=(BN_ULLONG) H(a0b0) + L(a0b0) + L(fix) + L(a1b1);
187 tmp=(BN_ULLONG) a1b1 + H(tmp) + H(a0b0) + H(fix) + H(a1b1) - s;
192 /* ret[3,2,1,0] += a1,a0 * b1,b0 */
193 BN_ULONG BN_mul_add_4words(ret,a0,a1,b0,b1)
195 BN_ULONG a0,a1,b0,b1;
198 BN_ULLONG fix,a0b0,a1b1,tmp;
201 fprintf(stdout,"%02X%02X%02X%02X",ret[3],ret[2],ret[1],ret[0]);
202 fprintf(stdout," + ( %02X%02X * %02X%02X ) - ",a1,a0,b1,b0);
228 a0b0=(BN_ULLONG)a0*b0;
232 a1b1=(BN_ULLONG)a1*b1;
233 tmp=(BN_ULLONG) H(tmp) + L(a0b0) + L(fix) + L(a1b1) + ret[1];
236 tmp=(BN_ULLONG) H(tmp) + L(a1b1) + H(a0b0) +
237 H(fix) + H(a1b1) -s + ret[2];
240 tmp=(BN_ULLONG) H(tmp) + H(a1b1) + ret[3];
243 fprintf(stdout,"%02X%02X%02X%02X%02X\n",H(tmp),ret[3],ret[2],ret[1],ret[0]);
248 /* ret[3,2,1,0] += a1,a0 * a1,a0 */
249 void BN_sqr_4words(ret,a0,a1)
256 tmp=(BN_ULLONG)a0*a0;
259 tmp2=(BN_ULLONG)a0*a1;
260 tmp=(BN_ULLONG)H(tmp)+L(tmp2)*2;
263 tmp=(BN_ULLONG)a1*a1+H(tmp)+H(tmp2)*2;
271 #define N3 (num+half)
273 #define word_cmp(r,a,b,num) \
280 if ((a)[(n)] > (b)[(n)]) \
282 else if ((a)[(n)] < (b)[(n)]) \
283 { (r)= -1; break; } \
288 /* (a->top == b->top) && (a->top >= 2) && !(a->top & 1) */
289 void bn_recursize_mul(r,t,a,b,num)
290 BN_ULONG *r,*t,*a,*b;
293 if ((num < 2) || (num&1))
296 /* fprintf(stderr,"num=%d half=%d\n",num,num/2);*/
298 BN_mul_4words(r,a[0],a[1],b[0],b[1]);
303 BN_mul_4words(&(r[0]),a[0],a[1],b[0],b[1]);
304 BN_mul_4words(&(r[4]),a[2],a[3],b[2],b[3]);
306 c =BN_mul_add_4words(&(r[2]),a[0],a[1],b[2],b[3]);
307 c+=BN_mul_add_4words(&(r[2]),a[2],a[3],b[0],b[1]);
309 bn_add_word(&(r[6]),c,2);
314 int carry,cmp_a,cmp_b;
316 word_cmp(cmp_a,&(a[0]),&(a[half]),half);
317 word_cmp(cmp_b,&(b[0]),&(b[half]),half);
319 switch (cmp_a*2+cmp_a+cmp_b)
322 bn_sub_words(&(t[N0]),&(a[N1]),&(a[N0]),half);
323 bn_sub_words(&(t[N1]),&(b[N0]),&(b[N1]),half);
324 bn_recursize_mul(&(r[N1]),&(t[N2]),
325 &(t[N0]),&(t[N1]),half);
326 bn_sub_words(&(r[N2]),&(r[N2]),&(t[N0]),half);
330 bn_sub_words(&(t[N0]),&(a[N1]),&(a[N0]),half);
331 bn_sub_words(&(t[N1]),&(b[N0]),&(b[N1]),half);
332 bn_recursize_mul(&(r[N1]),&(t[N2]),
333 &(t[N0]),&(t[N1]),half);
337 bn_sub_words(&(t[N0]),&(a[N0]),&(a[N1]),half);
338 bn_sub_words(&(t[N1]),&(b[N1]),&(b[N0]),half);
339 bn_recursize_mul(&(r[N1]),&(t[N2]),
340 &(t[N0]),&(t[N1]),half);
344 bn_sub_words(&(t[N0]),&(a[N1]),&(a[N0]),half);
345 bn_sub_words(&(t[N1]),&(b[N0]),&(b[N1]),half);
346 bn_recursize_mul(&(r[N1]),&(t[N2]),
347 &(t[N0]),&(t[N1]),half);
348 bn_sub_words(&(r[N2]),&(r[N2]),&(t[N1]),half);
352 memset(&(r[N1]),0,sizeof(BN_ULONG)*num);
356 bn_recursize_mul(&(t[N0]),&(t[N2]),&(a[N0]),&(b[N0]),half);
362 memcpy(&(r[N0]),&(t[N0]),half*sizeof(BN_ULONG));
363 if (bn_add_words(&(r[N1]),&(r[N1]),&(t[N1]),half))
364 { bn_add_word(&(t[N1]),1,half); }
366 carry+=bn_add_words(&(r[N1]),&(r[N1]),&(t[N0]),num);
368 bn_recursize_mul(&(t[N0]),&(t[N2]),&(a[N1]),&(b[N1]),half);
370 carry+=bn_add_words(&(r[N1]),&(r[N1]),&(t[N0]),num);
371 carry+=bn_add_words(&(r[N2]),&(r[N2]),&(t[N0]),half);
372 memcpy(&(r[N3]),&(t[N1]),half*sizeof(BN_ULONG));
374 bn_add_word(&(r[N3]),carry,half);
391 fprintf(stdout,"obase=16\n");
392 fprintf(stdout,"ibase=16\n");
397 r->top=(BITS*2)/BN_BITS2;
398 memset(r->d,0,sizeof(r->top)*sizeof(BN_ULONG));
399 memset(t->d,0,sizeof(r->top)*sizeof(BN_ULONG));
400 for (j=0; j<1000; j++)
403 /* BN_mul(r,a,b); /**/
404 bn_recursize_mul(r->d,t->d,a->d,b->d,a->top); /**/
406 BN_print(stdout,a); fprintf(stdout," * ");
407 BN_print(stdout,b); fprintf(stdout," - ");
408 BN_print(stdout,r); fprintf(stdout,"\n");