bn_mul.c revision 59191
1151497Sru/* crypto/bn/bn_mul.c */ 2151497Sru/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3151497Sru * All rights reserved. 4151497Sru * 5151497Sru * This package is an SSL implementation written 6151497Sru * by Eric Young (eay@cryptsoft.com). 7151497Sru * The implementation was written so as to conform with Netscapes SSL. 8151497Sru * 9151497Sru * This library is free for commercial and non-commercial use as long as 10151497Sru * the following conditions are aheared to. The following conditions 11151497Sru * apply to all code found in this distribution, be it the RC4, RSA, 12151497Sru * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13151497Sru * included with this distribution is covered by the same copyright terms 14151497Sru * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15151497Sru * 16151497Sru * Copyright remains Eric Young's, and as such any Copyright notices in 17151497Sru * the code are not to be removed. 18151497Sru * If this package is used in a product, Eric Young should be given attribution 19151497Sru * as the author of the parts of the library used. 20151497Sru * This can be in the form of a textual message at program startup or 21151497Sru * in documentation (online or textual) provided with the package. 22151497Sru * 23151497Sru * Redistribution and use in source and binary forms, with or without 24151497Sru * modification, are permitted provided that the following conditions 25151497Sru * are met: 26151497Sru * 1. Redistributions of source code must retain the copyright 27151497Sru * notice, this list of conditions and the following disclaimer. 28151497Sru * 2. Redistributions in binary form must reproduce the above copyright 29151497Sru * notice, this list of conditions and the following disclaimer in the 30151497Sru * documentation and/or other materials provided with the distribution. 31151497Sru * 3. All advertising materials mentioning features or use of this software 32151497Sru * must display the following acknowledgement: 33151497Sru * "This product includes cryptographic software written by 34151497Sru * Eric Young (eay@cryptsoft.com)" 35151497Sru * The word 'cryptographic' can be left out if the rouines from the library 36151497Sru * being used are not cryptographic related :-). 37151497Sru * 4. If you include any Windows specific code (or a derivative thereof) from 38151497Sru * the apps directory (application code) you must include an acknowledgement: 39151497Sru * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40151497Sru * 41151497Sru * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42151497Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43151497Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44151497Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45151497Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46151497Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47151497Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48151497Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49151497Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50151497Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51151497Sru * SUCH DAMAGE. 52151497Sru * 53151497Sru * The licence and distribution terms for any publically available version or 54151497Sru * derivative of this code cannot be changed. i.e. this code cannot simply be 55151497Sru * copied and put under another distribution licence 56151497Sru * [including the GNU Public Licence.] 57151497Sru */ 58151497Sru 59151497Sru#include <stdio.h> 60151497Sru#include "cryptlib.h" 61151497Sru#include "bn_lcl.h" 62151497Sru 63151497Sru#ifdef BN_RECURSION 64151497Sru/* Karatsuba recursive multiplication algorithm 65151497Sru * (cf. Knuth, The Art of Computer Programming, Vol. 2) */ 66151497Sru 67151497Sru/* r is 2*n2 words in size, 68151497Sru * a and b are both n2 words in size. 69151497Sru * n2 must be a power of 2. 70151497Sru * We multiply and return the result. 71151497Sru * t must be 2*n2 words in size 72151497Sru * We calculate 73151497Sru * a[0]*b[0] 74151497Sru * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) 75151497Sru * a[1]*b[1] 76151497Sru */ 77151497Sruvoid bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, 78151497Sru BN_ULONG *t) 79151497Sru { 80151497Sru int n=n2/2,c1,c2; 81151497Sru unsigned int neg,zero; 82151497Sru BN_ULONG ln,lo,*p; 83151497Sru 84151497Sru# ifdef BN_COUNT 85151497Sru printf(" bn_mul_recursive %d * %d\n",n2,n2); 86151497Sru# endif 87151497Sru# ifdef BN_MUL_COMBA 88151497Sru# if 0 89151497Sru if (n2 == 4) 90151497Sru { 91151497Sru bn_mul_comba4(r,a,b); 92151497Sru return; 93151497Sru } 94151497Sru# endif 95151497Sru if (n2 == 8) 96151497Sru { 97151497Sru bn_mul_comba8(r,a,b); 98151497Sru return; 99151497Sru } 100151497Sru# endif /* BN_MUL_COMBA */ 101151497Sru if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) 102151497Sru { 103151497Sru /* This should not happen */ 104151497Sru bn_mul_normal(r,a,n2,b,n2); 105151497Sru return; 106151497Sru } 107151497Sru /* r=(a[0]-a[1])*(b[1]-b[0]) */ 108151497Sru c1=bn_cmp_words(a,&(a[n]),n); 109151497Sru c2=bn_cmp_words(&(b[n]),b,n); 110151497Sru zero=neg=0; 111151497Sru switch (c1*3+c2) 112151497Sru { 113151497Sru case -4: 114151497Sru bn_sub_words(t, &(a[n]),a, n); /* - */ 115151497Sru bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 116151497Sru break; 117151497Sru case -3: 118151497Sru zero=1; 119151497Sru break; 120151497Sru case -2: 121151497Sru bn_sub_words(t, &(a[n]),a, n); /* - */ 122151497Sru bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ 123151497Sru neg=1; 124151497Sru break; 125151497Sru case -1: 126151497Sru case 0: 127151497Sru case 1: 128151497Sru zero=1; 129151497Sru break; 130151497Sru case 2: 131151497Sru bn_sub_words(t, a, &(a[n]),n); /* + */ 132151497Sru bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 133151497Sru neg=1; 134151497Sru break; 135151497Sru case 3: 136151497Sru zero=1; 137151497Sru break; 138151497Sru case 4: 139151497Sru bn_sub_words(t, a, &(a[n]),n); 140151497Sru bn_sub_words(&(t[n]),&(b[n]),b, n); 141151497Sru break; 142151497Sru } 143151497Sru 144151497Sru# ifdef BN_MUL_COMBA 145151497Sru if (n == 4) 146151497Sru { 147151497Sru if (!zero) 148151497Sru bn_mul_comba4(&(t[n2]),t,&(t[n])); 149151497Sru else 150151497Sru memset(&(t[n2]),0,8*sizeof(BN_ULONG)); 151151497Sru 152151497Sru bn_mul_comba4(r,a,b); 153151497Sru bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n])); 154151497Sru } 155151497Sru else if (n == 8) 156151497Sru { 157151497Sru if (!zero) 158151497Sru bn_mul_comba8(&(t[n2]),t,&(t[n])); 159151497Sru else 160151497Sru memset(&(t[n2]),0,16*sizeof(BN_ULONG)); 161151497Sru 162151497Sru bn_mul_comba8(r,a,b); 163151497Sru bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n])); 164151497Sru } 165151497Sru else 166151497Sru# endif /* BN_MUL_COMBA */ 167151497Sru { 168151497Sru p= &(t[n2*2]); 169151497Sru if (!zero) 170151497Sru bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); 171151497Sru else 172151497Sru memset(&(t[n2]),0,n2*sizeof(BN_ULONG)); 173151497Sru bn_mul_recursive(r,a,b,n,p); 174151497Sru bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p); 175151497Sru } 176151497Sru 177151497Sru /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign 178151497Sru * r[10] holds (a[0]*b[0]) 179151497Sru * r[32] holds (b[1]*b[1]) 180151497Sru */ 181151497Sru 182151497Sru c1=(int)(bn_add_words(t,r,&(r[n2]),n2)); 183151497Sru 184151497Sru if (neg) /* if t[32] is negative */ 185151497Sru { 186151497Sru c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2)); 187151497Sru } 188151497Sru else 189151497Sru { 190151497Sru /* Might have a carry */ 191151497Sru c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2)); 192151497Sru } 193151497Sru 194151497Sru /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) 195151497Sru * r[10] holds (a[0]*b[0]) 196151497Sru * r[32] holds (b[1]*b[1]) 197151497Sru * c1 holds the carry bits 198151497Sru */ 199151497Sru c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2)); 200151497Sru if (c1) 201151497Sru { 202151497Sru p= &(r[n+n2]); 203151497Sru lo= *p; 204151497Sru ln=(lo+c1)&BN_MASK2; 205151497Sru *p=ln; 206151497Sru 207151497Sru /* The overflow will stop before we over write 208151497Sru * words we should not overwrite */ 209151497Sru if (ln < (BN_ULONG)c1) 210151497Sru { 211151497Sru do { 212151497Sru p++; 213151497Sru lo= *p; 214151497Sru ln=(lo+1)&BN_MASK2; 215151497Sru *p=ln; 216151497Sru } while (ln == 0); 217151497Sru } 218151497Sru } 219151497Sru } 220151497Sru 221151497Sru/* n+tn is the word length 222151497Sru * t needs to be n*4 is size, as does r */ 223151497Sruvoid bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn, 224151497Sru int n, BN_ULONG *t) 225151497Sru { 226 int i,j,n2=n*2; 227 unsigned int c1,c2,neg,zero; 228 BN_ULONG ln,lo,*p; 229 230# ifdef BN_COUNT 231 printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n); 232# endif 233 if (n < 8) 234 { 235 i=tn+n; 236 bn_mul_normal(r,a,i,b,i); 237 return; 238 } 239 240 /* r=(a[0]-a[1])*(b[1]-b[0]) */ 241 c1=bn_cmp_words(a,&(a[n]),n); 242 c2=bn_cmp_words(&(b[n]),b,n); 243 zero=neg=0; 244 switch (c1*3+c2) 245 { 246 case -4: 247 bn_sub_words(t, &(a[n]),a, n); /* - */ 248 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 249 break; 250 case -3: 251 zero=1; 252 /* break; */ 253 case -2: 254 bn_sub_words(t, &(a[n]),a, n); /* - */ 255 bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ 256 neg=1; 257 break; 258 case -1: 259 case 0: 260 case 1: 261 zero=1; 262 /* break; */ 263 case 2: 264 bn_sub_words(t, a, &(a[n]),n); /* + */ 265 bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ 266 neg=1; 267 break; 268 case 3: 269 zero=1; 270 /* break; */ 271 case 4: 272 bn_sub_words(t, a, &(a[n]),n); 273 bn_sub_words(&(t[n]),&(b[n]),b, n); 274 break; 275 } 276 /* The zero case isn't yet implemented here. The speedup 277 would probably be negligible. */ 278# if 0 279 if (n == 4) 280 { 281 bn_mul_comba4(&(t[n2]),t,&(t[n])); 282 bn_mul_comba4(r,a,b); 283 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); 284 memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2)); 285 } 286 else 287# endif 288 if (n == 8) 289 { 290 bn_mul_comba8(&(t[n2]),t,&(t[n])); 291 bn_mul_comba8(r,a,b); 292 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); 293 memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2)); 294 } 295 else 296 { 297 p= &(t[n2*2]); 298 bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); 299 bn_mul_recursive(r,a,b,n,p); 300 i=n/2; 301 /* If there is only a bottom half to the number, 302 * just do it */ 303 j=tn-i; 304 if (j == 0) 305 { 306 bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p); 307 memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2)); 308 } 309 else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */ 310 { 311 bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]), 312 j,i,p); 313 memset(&(r[n2+tn*2]),0, 314 sizeof(BN_ULONG)*(n2-tn*2)); 315 } 316 else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ 317 { 318 memset(&(r[n2]),0,sizeof(BN_ULONG)*n2); 319 if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL) 320 { 321 bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); 322 } 323 else 324 { 325 for (;;) 326 { 327 i/=2; 328 if (i < tn) 329 { 330 bn_mul_part_recursive(&(r[n2]), 331 &(a[n]),&(b[n]), 332 tn-i,i,p); 333 break; 334 } 335 else if (i == tn) 336 { 337 bn_mul_recursive(&(r[n2]), 338 &(a[n]),&(b[n]), 339 i,p); 340 break; 341 } 342 } 343 } 344 } 345 } 346 347 /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign 348 * r[10] holds (a[0]*b[0]) 349 * r[32] holds (b[1]*b[1]) 350 */ 351 352 c1=(int)(bn_add_words(t,r,&(r[n2]),n2)); 353 354 if (neg) /* if t[32] is negative */ 355 { 356 c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2)); 357 } 358 else 359 { 360 /* Might have a carry */ 361 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2)); 362 } 363 364 /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) 365 * r[10] holds (a[0]*b[0]) 366 * r[32] holds (b[1]*b[1]) 367 * c1 holds the carry bits 368 */ 369 c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2)); 370 if (c1) 371 { 372 p= &(r[n+n2]); 373 lo= *p; 374 ln=(lo+c1)&BN_MASK2; 375 *p=ln; 376 377 /* The overflow will stop before we over write 378 * words we should not overwrite */ 379 if (ln < c1) 380 { 381 do { 382 p++; 383 lo= *p; 384 ln=(lo+1)&BN_MASK2; 385 *p=ln; 386 } while (ln == 0); 387 } 388 } 389 } 390 391/* a and b must be the same size, which is n2. 392 * r needs to be n2 words and t needs to be n2*2 393 */ 394void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, 395 BN_ULONG *t) 396 { 397 int n=n2/2; 398 399# ifdef BN_COUNT 400 printf(" bn_mul_low_recursive %d * %d\n",n2,n2); 401# endif 402 403 bn_mul_recursive(r,a,b,n,&(t[0])); 404 if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) 405 { 406 bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2])); 407 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n); 408 bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2])); 409 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n); 410 } 411 else 412 { 413 bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n); 414 bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n); 415 bn_add_words(&(r[n]),&(r[n]),&(t[0]),n); 416 bn_add_words(&(r[n]),&(r[n]),&(t[n]),n); 417 } 418 } 419 420/* a and b must be the same size, which is n2. 421 * r needs to be n2 words and t needs to be n2*2 422 * l is the low words of the output. 423 * t needs to be n2*3 424 */ 425void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, 426 BN_ULONG *t) 427 { 428 int i,n; 429 int c1,c2; 430 int neg,oneg,zero; 431 BN_ULONG ll,lc,*lp,*mp; 432 433# ifdef BN_COUNT 434 printf(" bn_mul_high %d * %d\n",n2,n2); 435# endif 436 n=n2/2; 437 438 /* Calculate (al-ah)*(bh-bl) */ 439 neg=zero=0; 440 c1=bn_cmp_words(&(a[0]),&(a[n]),n); 441 c2=bn_cmp_words(&(b[n]),&(b[0]),n); 442 switch (c1*3+c2) 443 { 444 case -4: 445 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n); 446 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n); 447 break; 448 case -3: 449 zero=1; 450 break; 451 case -2: 452 bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n); 453 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n); 454 neg=1; 455 break; 456 case -1: 457 case 0: 458 case 1: 459 zero=1; 460 break; 461 case 2: 462 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n); 463 bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n); 464 neg=1; 465 break; 466 case 3: 467 zero=1; 468 break; 469 case 4: 470 bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n); 471 bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n); 472 break; 473 } 474 475 oneg=neg; 476 /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */ 477 /* r[10] = (a[1]*b[1]) */ 478# ifdef BN_MUL_COMBA 479 if (n == 8) 480 { 481 bn_mul_comba8(&(t[0]),&(r[0]),&(r[n])); 482 bn_mul_comba8(r,&(a[n]),&(b[n])); 483 } 484 else 485# endif 486 { 487 bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2])); 488 bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2])); 489 } 490 491 /* s0 == low(al*bl) 492 * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl) 493 * We know s0 and s1 so the only unknown is high(al*bl) 494 * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl)) 495 * high(al*bl) == s1 - (r[0]+l[0]+t[0]) 496 */ 497 if (l != NULL) 498 { 499 lp= &(t[n2+n]); 500 c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n)); 501 } 502 else 503 { 504 c1=0; 505 lp= &(r[0]); 506 } 507 508 if (neg) 509 neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n)); 510 else 511 { 512 bn_add_words(&(t[n2]),lp,&(t[0]),n); 513 neg=0; 514 } 515 516 if (l != NULL) 517 { 518 bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n); 519 } 520 else 521 { 522 lp= &(t[n2+n]); 523 mp= &(t[n2]); 524 for (i=0; i<n; i++) 525 lp[i]=((~mp[i])+1)&BN_MASK2; 526 } 527 528 /* s[0] = low(al*bl) 529 * t[3] = high(al*bl) 530 * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign 531 * r[10] = (a[1]*b[1]) 532 */ 533 /* R[10] = al*bl 534 * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0]) 535 * R[32] = ah*bh 536 */ 537 /* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow) 538 * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow) 539 * R[3]=r[1]+(carry/borrow) 540 */ 541 if (l != NULL) 542 { 543 lp= &(t[n2]); 544 c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n)); 545 } 546 else 547 { 548 lp= &(t[n2+n]); 549 c1=0; 550 } 551 c1+=(int)(bn_add_words(&(t[n2]),lp, &(r[0]),n)); 552 if (oneg) 553 c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n)); 554 else 555 c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n)); 556 557 c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n)); 558 c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n)); 559 if (oneg) 560 c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n)); 561 else 562 c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n)); 563 564 if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */ 565 { 566 i=0; 567 if (c1 > 0) 568 { 569 lc=c1; 570 do { 571 ll=(r[i]+lc)&BN_MASK2; 572 r[i++]=ll; 573 lc=(lc > ll); 574 } while (lc); 575 } 576 else 577 { 578 lc= -c1; 579 do { 580 ll=r[i]; 581 r[i++]=(ll-lc)&BN_MASK2; 582 lc=(lc > ll); 583 } while (lc); 584 } 585 } 586 if (c2 != 0) /* Add starting at r[1] */ 587 { 588 i=n; 589 if (c2 > 0) 590 { 591 lc=c2; 592 do { 593 ll=(r[i]+lc)&BN_MASK2; 594 r[i++]=ll; 595 lc=(lc > ll); 596 } while (lc); 597 } 598 else 599 { 600 lc= -c2; 601 do { 602 ll=r[i]; 603 r[i++]=(ll-lc)&BN_MASK2; 604 lc=(lc > ll); 605 } while (lc); 606 } 607 } 608 } 609#endif /* BN_RECURSION */ 610 611int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) 612 { 613 int top,al,bl; 614 BIGNUM *rr; 615 int ret = 0; 616#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) 617 int i; 618#endif 619#ifdef BN_RECURSION 620 BIGNUM *t; 621 int j,k; 622#endif 623 624#ifdef BN_COUNT 625 printf("BN_mul %d * %d\n",a->top,b->top); 626#endif 627 628 bn_check_top(a); 629 bn_check_top(b); 630 bn_check_top(r); 631 632 al=a->top; 633 bl=b->top; 634 r->neg=a->neg^b->neg; 635 636 if ((al == 0) || (bl == 0)) 637 { 638 BN_zero(r); 639 return(1); 640 } 641 top=al+bl; 642 643 BN_CTX_start(ctx); 644 if ((r == a) || (r == b)) 645 { 646 if ((rr = BN_CTX_get(ctx)) == NULL) goto err; 647 } 648 else 649 rr = r; 650 651#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) 652 i = al-bl; 653#endif 654#ifdef BN_MUL_COMBA 655 if (i == 0) 656 { 657# if 0 658 if (al == 4) 659 { 660 if (bn_wexpand(rr,8) == NULL) goto err; 661 rr->top=8; 662 bn_mul_comba4(rr->d,a->d,b->d); 663 goto end; 664 } 665# endif 666 if (al == 8) 667 { 668 if (bn_wexpand(rr,16) == NULL) goto err; 669 rr->top=16; 670 bn_mul_comba8(rr->d,a->d,b->d); 671 goto end; 672 } 673 } 674#endif /* BN_MUL_COMBA */ 675#ifdef BN_RECURSION 676 if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) 677 { 678 if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA)) 679 { 680 bn_wexpand(b,al); 681 b->d[bl]=0; 682 bl++; 683 i--; 684 } 685 else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA)) 686 { 687 bn_wexpand(a,bl); 688 a->d[al]=0; 689 al++; 690 i++; 691 } 692 if (i == 0) 693 { 694 /* symmetric and > 4 */ 695 /* 16 or larger */ 696 j=BN_num_bits_word((BN_ULONG)al); 697 j=1<<(j-1); 698 k=j+j; 699 t = BN_CTX_get(ctx); 700 if (al == j) /* exact multiple */ 701 { 702 bn_wexpand(t,k*2); 703 bn_wexpand(rr,k*2); 704 bn_mul_recursive(rr->d,a->d,b->d,al,t->d); 705 } 706 else 707 { 708 bn_wexpand(a,k); 709 bn_wexpand(b,k); 710 bn_wexpand(t,k*4); 711 bn_wexpand(rr,k*4); 712 for (i=a->top; i<k; i++) 713 a->d[i]=0; 714 for (i=b->top; i<k; i++) 715 b->d[i]=0; 716 bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); 717 } 718 rr->top=top; 719 goto end; 720 } 721 } 722#endif /* BN_RECURSION */ 723 if (bn_wexpand(rr,top) == NULL) goto err; 724 rr->top=top; 725 bn_mul_normal(rr->d,a->d,al,b->d,bl); 726 727#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) 728end: 729#endif 730 bn_fix_top(rr); 731 if (r != rr) BN_copy(r,rr); 732 ret=1; 733err: 734 BN_CTX_end(ctx); 735 return(ret); 736 } 737 738void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) 739 { 740 BN_ULONG *rr; 741 742#ifdef BN_COUNT 743 printf(" bn_mul_normal %d * %d\n",na,nb); 744#endif 745 746 if (na < nb) 747 { 748 int itmp; 749 BN_ULONG *ltmp; 750 751 itmp=na; na=nb; nb=itmp; 752 ltmp=a; a=b; b=ltmp; 753 754 } 755 rr= &(r[na]); 756 rr[0]=bn_mul_words(r,a,na,b[0]); 757 758 for (;;) 759 { 760 if (--nb <= 0) return; 761 rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]); 762 if (--nb <= 0) return; 763 rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]); 764 if (--nb <= 0) return; 765 rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]); 766 if (--nb <= 0) return; 767 rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]); 768 rr+=4; 769 r+=4; 770 b+=4; 771 } 772 } 773 774void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) 775 { 776#ifdef BN_COUNT 777 printf(" bn_mul_low_normal %d * %d\n",n,n); 778#endif 779 bn_mul_words(r,a,n,b[0]); 780 781 for (;;) 782 { 783 if (--n <= 0) return; 784 bn_mul_add_words(&(r[1]),a,n,b[1]); 785 if (--n <= 0) return; 786 bn_mul_add_words(&(r[2]),a,n,b[2]); 787 if (--n <= 0) return; 788 bn_mul_add_words(&(r[3]),a,n,b[3]); 789 if (--n <= 0) return; 790 bn_mul_add_words(&(r[4]),a,n,b[4]); 791 r+=4; 792 b+=4; 793 } 794 } 795