bn_mul.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  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(__i386) || defined(__i386__)) || defined(__DJGPP__) /* Assembler implementation exists only for x86 */
  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. unsigned 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 < 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. if (!BN_zero(r)) goto err;
  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_fix_top(rr);
  1022. if (r != rr) BN_copy(r,rr);
  1023. ret=1;
  1024. err:
  1025. BN_CTX_end(ctx);
  1026. return(ret);
  1027. }
  1028. void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
  1029. {
  1030. BN_ULONG *rr;
  1031. #ifdef BN_COUNT
  1032. fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
  1033. #endif
  1034. if (na < nb)
  1035. {
  1036. int itmp;
  1037. BN_ULONG *ltmp;
  1038. itmp=na; na=nb; nb=itmp;
  1039. ltmp=a; a=b; b=ltmp;
  1040. }
  1041. rr= &(r[na]);
  1042. if (nb <= 0)
  1043. {
  1044. (void)bn_mul_words(r,a,na,0);
  1045. return;
  1046. }
  1047. else
  1048. rr[0]=bn_mul_words(r,a,na,b[0]);
  1049. for (;;)
  1050. {
  1051. if (--nb <= 0) return;
  1052. rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
  1053. if (--nb <= 0) return;
  1054. rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
  1055. if (--nb <= 0) return;
  1056. rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
  1057. if (--nb <= 0) return;
  1058. rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
  1059. rr+=4;
  1060. r+=4;
  1061. b+=4;
  1062. }
  1063. }
  1064. void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
  1065. {
  1066. #ifdef BN_COUNT
  1067. fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
  1068. #endif
  1069. bn_mul_words(r,a,n,b[0]);
  1070. for (;;)
  1071. {
  1072. if (--n <= 0) return;
  1073. bn_mul_add_words(&(r[1]),a,n,b[1]);
  1074. if (--n <= 0) return;
  1075. bn_mul_add_words(&(r[2]),a,n,b[2]);
  1076. if (--n <= 0) return;
  1077. bn_mul_add_words(&(r[3]),a,n,b[3]);
  1078. if (--n <= 0) return;
  1079. bn_mul_add_words(&(r[4]),a,n,b[4]);
  1080. r+=4;
  1081. b+=4;
  1082. }
  1083. }