bn_mul.c 24 KB

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