bn_mul.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166
  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. /* dnX may not be positive, but n2/2+dnX has to be */
  359. void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
  360. int dna, int dnb, BN_ULONG *t)
  361. {
  362. int n=n2/2,c1,c2;
  363. int tna=n+dna, tnb=n+dnb;
  364. unsigned int neg,zero;
  365. BN_ULONG ln,lo,*p;
  366. # ifdef BN_COUNT
  367. fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb);
  368. # endif
  369. # ifdef BN_MUL_COMBA
  370. # if 0
  371. if (n2 == 4)
  372. {
  373. bn_mul_comba4(r,a,b);
  374. return;
  375. }
  376. # endif
  377. /* Only call bn_mul_comba 8 if n2 == 8 and the
  378. * two arrays are complete [steve]
  379. */
  380. if (n2 == 8 && dna == 0 && dnb == 0)
  381. {
  382. bn_mul_comba8(r,a,b);
  383. return;
  384. }
  385. # endif /* BN_MUL_COMBA */
  386. /* Else do normal multiply */
  387. if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
  388. {
  389. bn_mul_normal(r,a,n2+dna,b,n2+dnb);
  390. if ((dna + dnb) < 0)
  391. memset(&r[2*n2 + dna + dnb], 0,
  392. sizeof(BN_ULONG) * -(dna + dnb));
  393. return;
  394. }
  395. /* r=(a[0]-a[1])*(b[1]-b[0]) */
  396. c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
  397. c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
  398. zero=neg=0;
  399. switch (c1*3+c2)
  400. {
  401. case -4:
  402. bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
  403. bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
  404. break;
  405. case -3:
  406. zero=1;
  407. break;
  408. case -2:
  409. bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
  410. bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
  411. neg=1;
  412. break;
  413. case -1:
  414. case 0:
  415. case 1:
  416. zero=1;
  417. break;
  418. case 2:
  419. bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
  420. bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
  421. neg=1;
  422. break;
  423. case 3:
  424. zero=1;
  425. break;
  426. case 4:
  427. bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
  428. bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
  429. break;
  430. }
  431. # ifdef BN_MUL_COMBA
  432. if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
  433. extra args to do this well */
  434. {
  435. if (!zero)
  436. bn_mul_comba4(&(t[n2]),t,&(t[n]));
  437. else
  438. memset(&(t[n2]),0,8*sizeof(BN_ULONG));
  439. bn_mul_comba4(r,a,b);
  440. bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
  441. }
  442. else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
  443. take extra args to do this
  444. well */
  445. {
  446. if (!zero)
  447. bn_mul_comba8(&(t[n2]),t,&(t[n]));
  448. else
  449. memset(&(t[n2]),0,16*sizeof(BN_ULONG));
  450. bn_mul_comba8(r,a,b);
  451. bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
  452. }
  453. else
  454. # endif /* BN_MUL_COMBA */
  455. {
  456. p= &(t[n2*2]);
  457. if (!zero)
  458. bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
  459. else
  460. memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
  461. bn_mul_recursive(r,a,b,n,0,0,p);
  462. bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
  463. }
  464. /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
  465. * r[10] holds (a[0]*b[0])
  466. * r[32] holds (b[1]*b[1])
  467. */
  468. c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
  469. if (neg) /* if t[32] is negative */
  470. {
  471. c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
  472. }
  473. else
  474. {
  475. /* Might have a carry */
  476. c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
  477. }
  478. /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
  479. * r[10] holds (a[0]*b[0])
  480. * r[32] holds (b[1]*b[1])
  481. * c1 holds the carry bits
  482. */
  483. c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
  484. if (c1)
  485. {
  486. p= &(r[n+n2]);
  487. lo= *p;
  488. ln=(lo+c1)&BN_MASK2;
  489. *p=ln;
  490. /* The overflow will stop before we over write
  491. * words we should not overwrite */
  492. if (ln < (BN_ULONG)c1)
  493. {
  494. do {
  495. p++;
  496. lo= *p;
  497. ln=(lo+1)&BN_MASK2;
  498. *p=ln;
  499. } while (ln == 0);
  500. }
  501. }
  502. }
  503. /* n+tn is the word length
  504. * t needs to be n*4 is size, as does r */
  505. /* tnX may not be negative but less than n */
  506. void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
  507. int tna, int tnb, BN_ULONG *t)
  508. {
  509. int i,j,n2=n*2;
  510. int c1,c2,neg;
  511. BN_ULONG ln,lo,*p;
  512. # ifdef BN_COUNT
  513. fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
  514. n, tna, n, tnb);
  515. # endif
  516. if (n < 8)
  517. {
  518. bn_mul_normal(r,a,n+tna,b,n+tnb);
  519. return;
  520. }
  521. /* r=(a[0]-a[1])*(b[1]-b[0]) */
  522. c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
  523. c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
  524. neg=0;
  525. switch (c1*3+c2)
  526. {
  527. case -4:
  528. bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
  529. bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
  530. break;
  531. case -3:
  532. /* break; */
  533. case -2:
  534. bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
  535. bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
  536. neg=1;
  537. break;
  538. case -1:
  539. case 0:
  540. case 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. /* break; */
  549. case 4:
  550. bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
  551. bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
  552. break;
  553. }
  554. /* The zero case isn't yet implemented here. The speedup
  555. would probably be negligible. */
  556. # if 0
  557. if (n == 4)
  558. {
  559. bn_mul_comba4(&(t[n2]),t,&(t[n]));
  560. bn_mul_comba4(r,a,b);
  561. bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
  562. memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
  563. }
  564. else
  565. # endif
  566. if (n == 8)
  567. {
  568. bn_mul_comba8(&(t[n2]),t,&(t[n]));
  569. bn_mul_comba8(r,a,b);
  570. bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
  571. memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
  572. }
  573. else
  574. {
  575. p= &(t[n2*2]);
  576. bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
  577. bn_mul_recursive(r,a,b,n,0,0,p);
  578. i=n/2;
  579. /* If there is only a bottom half to the number,
  580. * just do it */
  581. if (tna > tnb)
  582. j = tna - i;
  583. else
  584. j = tnb - i;
  585. if (j == 0)
  586. {
  587. bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
  588. i,tna-i,tnb-i,p);
  589. memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
  590. }
  591. else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
  592. {
  593. bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
  594. i,tna-i,tnb-i,p);
  595. memset(&(r[n2+tna+tnb]),0,
  596. sizeof(BN_ULONG)*(n2-tna-tnb));
  597. }
  598. else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
  599. {
  600. memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
  601. if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
  602. && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
  603. {
  604. bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
  605. }
  606. else
  607. {
  608. for (;;)
  609. {
  610. i/=2;
  611. /* these simplified conditions work
  612. * exclusively because difference
  613. * between tna and tnb is 1 or 0 */
  614. if (i < tna || i < tnb)
  615. {
  616. bn_mul_part_recursive(&(r[n2]),
  617. &(a[n]),&(b[n]),
  618. i,tna-i,tnb-i,p);
  619. break;
  620. }
  621. else if (i == tna || i == tnb)
  622. {
  623. bn_mul_recursive(&(r[n2]),
  624. &(a[n]),&(b[n]),
  625. i,tna-i,tnb-i,p);
  626. break;
  627. }
  628. }
  629. }
  630. }
  631. }
  632. /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
  633. * r[10] holds (a[0]*b[0])
  634. * r[32] holds (b[1]*b[1])
  635. */
  636. c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
  637. if (neg) /* if t[32] is negative */
  638. {
  639. c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
  640. }
  641. else
  642. {
  643. /* Might have a carry */
  644. c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
  645. }
  646. /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
  647. * r[10] holds (a[0]*b[0])
  648. * r[32] holds (b[1]*b[1])
  649. * c1 holds the carry bits
  650. */
  651. c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
  652. if (c1)
  653. {
  654. p= &(r[n+n2]);
  655. lo= *p;
  656. ln=(lo+c1)&BN_MASK2;
  657. *p=ln;
  658. /* The overflow will stop before we over write
  659. * words we should not overwrite */
  660. if (ln < (BN_ULONG)c1)
  661. {
  662. do {
  663. p++;
  664. lo= *p;
  665. ln=(lo+1)&BN_MASK2;
  666. *p=ln;
  667. } while (ln == 0);
  668. }
  669. }
  670. }
  671. /* a and b must be the same size, which is n2.
  672. * r needs to be n2 words and t needs to be n2*2
  673. */
  674. void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
  675. BN_ULONG *t)
  676. {
  677. int n=n2/2;
  678. # ifdef BN_COUNT
  679. fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
  680. # endif
  681. bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
  682. if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
  683. {
  684. bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
  685. bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
  686. bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
  687. bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
  688. }
  689. else
  690. {
  691. bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
  692. bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
  693. bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
  694. bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
  695. }
  696. }
  697. /* a and b must be the same size, which is n2.
  698. * r needs to be n2 words and t needs to be n2*2
  699. * l is the low words of the output.
  700. * t needs to be n2*3
  701. */
  702. void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
  703. BN_ULONG *t)
  704. {
  705. int i,n;
  706. int c1,c2;
  707. int neg,oneg,zero;
  708. BN_ULONG ll,lc,*lp,*mp;
  709. # ifdef BN_COUNT
  710. fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
  711. # endif
  712. n=n2/2;
  713. /* Calculate (al-ah)*(bh-bl) */
  714. neg=zero=0;
  715. c1=bn_cmp_words(&(a[0]),&(a[n]),n);
  716. c2=bn_cmp_words(&(b[n]),&(b[0]),n);
  717. switch (c1*3+c2)
  718. {
  719. case -4:
  720. bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
  721. bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
  722. break;
  723. case -3:
  724. zero=1;
  725. break;
  726. case -2:
  727. bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
  728. bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
  729. neg=1;
  730. break;
  731. case -1:
  732. case 0:
  733. case 1:
  734. zero=1;
  735. break;
  736. case 2:
  737. bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
  738. bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
  739. neg=1;
  740. break;
  741. case 3:
  742. zero=1;
  743. break;
  744. case 4:
  745. bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
  746. bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
  747. break;
  748. }
  749. oneg=neg;
  750. /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
  751. /* r[10] = (a[1]*b[1]) */
  752. # ifdef BN_MUL_COMBA
  753. if (n == 8)
  754. {
  755. bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
  756. bn_mul_comba8(r,&(a[n]),&(b[n]));
  757. }
  758. else
  759. # endif
  760. {
  761. bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
  762. bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
  763. }
  764. /* s0 == low(al*bl)
  765. * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
  766. * We know s0 and s1 so the only unknown is high(al*bl)
  767. * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
  768. * high(al*bl) == s1 - (r[0]+l[0]+t[0])
  769. */
  770. if (l != NULL)
  771. {
  772. lp= &(t[n2+n]);
  773. c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
  774. }
  775. else
  776. {
  777. c1=0;
  778. lp= &(r[0]);
  779. }
  780. if (neg)
  781. neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
  782. else
  783. {
  784. bn_add_words(&(t[n2]),lp,&(t[0]),n);
  785. neg=0;
  786. }
  787. if (l != NULL)
  788. {
  789. bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
  790. }
  791. else
  792. {
  793. lp= &(t[n2+n]);
  794. mp= &(t[n2]);
  795. for (i=0; i<n; i++)
  796. lp[i]=((~mp[i])+1)&BN_MASK2;
  797. }
  798. /* s[0] = low(al*bl)
  799. * t[3] = high(al*bl)
  800. * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
  801. * r[10] = (a[1]*b[1])
  802. */
  803. /* R[10] = al*bl
  804. * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
  805. * R[32] = ah*bh
  806. */
  807. /* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
  808. * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
  809. * R[3]=r[1]+(carry/borrow)
  810. */
  811. if (l != NULL)
  812. {
  813. lp= &(t[n2]);
  814. c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
  815. }
  816. else
  817. {
  818. lp= &(t[n2+n]);
  819. c1=0;
  820. }
  821. c1+=(int)(bn_add_words(&(t[n2]),lp, &(r[0]),n));
  822. if (oneg)
  823. c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
  824. else
  825. c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
  826. c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
  827. c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
  828. if (oneg)
  829. c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
  830. else
  831. c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
  832. if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
  833. {
  834. i=0;
  835. if (c1 > 0)
  836. {
  837. lc=c1;
  838. do {
  839. ll=(r[i]+lc)&BN_MASK2;
  840. r[i++]=ll;
  841. lc=(lc > ll);
  842. } while (lc);
  843. }
  844. else
  845. {
  846. lc= -c1;
  847. do {
  848. ll=r[i];
  849. r[i++]=(ll-lc)&BN_MASK2;
  850. lc=(lc > ll);
  851. } while (lc);
  852. }
  853. }
  854. if (c2 != 0) /* Add starting at r[1] */
  855. {
  856. i=n;
  857. if (c2 > 0)
  858. {
  859. lc=c2;
  860. do {
  861. ll=(r[i]+lc)&BN_MASK2;
  862. r[i++]=ll;
  863. lc=(lc > ll);
  864. } while (lc);
  865. }
  866. else
  867. {
  868. lc= -c2;
  869. do {
  870. ll=r[i];
  871. r[i++]=(ll-lc)&BN_MASK2;
  872. lc=(lc > ll);
  873. } while (lc);
  874. }
  875. }
  876. }
  877. #endif /* BN_RECURSION */
  878. int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
  879. {
  880. int ret=0;
  881. int top,al,bl;
  882. BIGNUM *rr;
  883. #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
  884. int i;
  885. #endif
  886. #ifdef BN_RECURSION
  887. BIGNUM *t=NULL;
  888. int j=0,k;
  889. #endif
  890. #ifdef BN_COUNT
  891. fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
  892. #endif
  893. bn_check_top(a);
  894. bn_check_top(b);
  895. bn_check_top(r);
  896. al=a->top;
  897. bl=b->top;
  898. if ((al == 0) || (bl == 0))
  899. {
  900. BN_zero(r);
  901. return(1);
  902. }
  903. top=al+bl;
  904. BN_CTX_start(ctx);
  905. if ((r == a) || (r == b))
  906. {
  907. if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
  908. }
  909. else
  910. rr = r;
  911. rr->neg=a->neg^b->neg;
  912. #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
  913. i = al-bl;
  914. #endif
  915. #ifdef BN_MUL_COMBA
  916. if (i == 0)
  917. {
  918. # if 0
  919. if (al == 4)
  920. {
  921. if (bn_wexpand(rr,8) == NULL) goto err;
  922. rr->top=8;
  923. bn_mul_comba4(rr->d,a->d,b->d);
  924. goto end;
  925. }
  926. # endif
  927. if (al == 8)
  928. {
  929. if (bn_wexpand(rr,16) == NULL) goto err;
  930. rr->top=16;
  931. bn_mul_comba8(rr->d,a->d,b->d);
  932. goto end;
  933. }
  934. }
  935. #endif /* BN_MUL_COMBA */
  936. #ifdef BN_RECURSION
  937. if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
  938. {
  939. if (i >= -1 && i <= 1)
  940. {
  941. /* Find out the power of two lower or equal
  942. to the longest of the two numbers */
  943. if (i >= 0)
  944. {
  945. j = BN_num_bits_word((BN_ULONG)al);
  946. }
  947. if (i == -1)
  948. {
  949. j = BN_num_bits_word((BN_ULONG)bl);
  950. }
  951. j = 1<<(j-1);
  952. assert(j <= al || j <= bl);
  953. k = j+j;
  954. t = BN_CTX_get(ctx);
  955. if (t == NULL)
  956. goto err;
  957. if (al > j || bl > j)
  958. {
  959. if (bn_wexpand(t,k*4) == NULL) goto err;
  960. if (bn_wexpand(rr,k*4) == NULL) goto err;
  961. bn_mul_part_recursive(rr->d,a->d,b->d,
  962. j,al-j,bl-j,t->d);
  963. }
  964. else /* al <= j || bl <= j */
  965. {
  966. if (bn_wexpand(t,k*2) == NULL) goto err;
  967. if (bn_wexpand(rr,k*2) == NULL) goto err;
  968. bn_mul_recursive(rr->d,a->d,b->d,
  969. j,al-j,bl-j,t->d);
  970. }
  971. rr->top=top;
  972. goto end;
  973. }
  974. #if 0
  975. if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
  976. {
  977. BIGNUM *tmp_bn = (BIGNUM *)b;
  978. if (bn_wexpand(tmp_bn,al) == NULL) goto err;
  979. tmp_bn->d[bl]=0;
  980. bl++;
  981. i--;
  982. }
  983. else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
  984. {
  985. BIGNUM *tmp_bn = (BIGNUM *)a;
  986. if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
  987. tmp_bn->d[al]=0;
  988. al++;
  989. i++;
  990. }
  991. if (i == 0)
  992. {
  993. /* symmetric and > 4 */
  994. /* 16 or larger */
  995. j=BN_num_bits_word((BN_ULONG)al);
  996. j=1<<(j-1);
  997. k=j+j;
  998. t = BN_CTX_get(ctx);
  999. if (al == j) /* exact multiple */
  1000. {
  1001. if (bn_wexpand(t,k*2) == NULL) goto err;
  1002. if (bn_wexpand(rr,k*2) == NULL) goto err;
  1003. bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
  1004. }
  1005. else
  1006. {
  1007. if (bn_wexpand(t,k*4) == NULL) goto err;
  1008. if (bn_wexpand(rr,k*4) == NULL) goto err;
  1009. bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
  1010. }
  1011. rr->top=top;
  1012. goto end;
  1013. }
  1014. #endif
  1015. }
  1016. #endif /* BN_RECURSION */
  1017. if (bn_wexpand(rr,top) == NULL) goto err;
  1018. rr->top=top;
  1019. bn_mul_normal(rr->d,a->d,al,b->d,bl);
  1020. #if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
  1021. end:
  1022. #endif
  1023. bn_correct_top(rr);
  1024. if (r != rr) BN_copy(r,rr);
  1025. ret=1;
  1026. err:
  1027. bn_check_top(r);
  1028. BN_CTX_end(ctx);
  1029. return(ret);
  1030. }
  1031. void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
  1032. {
  1033. BN_ULONG *rr;
  1034. #ifdef BN_COUNT
  1035. fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
  1036. #endif
  1037. if (na < nb)
  1038. {
  1039. int itmp;
  1040. BN_ULONG *ltmp;
  1041. itmp=na; na=nb; nb=itmp;
  1042. ltmp=a; a=b; b=ltmp;
  1043. }
  1044. rr= &(r[na]);
  1045. if (nb <= 0)
  1046. {
  1047. (void)bn_mul_words(r,a,na,0);
  1048. return;
  1049. }
  1050. else
  1051. rr[0]=bn_mul_words(r,a,na,b[0]);
  1052. for (;;)
  1053. {
  1054. if (--nb <= 0) return;
  1055. rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
  1056. if (--nb <= 0) return;
  1057. rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
  1058. if (--nb <= 0) return;
  1059. rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
  1060. if (--nb <= 0) return;
  1061. rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
  1062. rr+=4;
  1063. r+=4;
  1064. b+=4;
  1065. }
  1066. }
  1067. void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
  1068. {
  1069. #ifdef BN_COUNT
  1070. fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
  1071. #endif
  1072. bn_mul_words(r,a,n,b[0]);
  1073. for (;;)
  1074. {
  1075. if (--n <= 0) return;
  1076. bn_mul_add_words(&(r[1]),a,n,b[1]);
  1077. if (--n <= 0) return;
  1078. bn_mul_add_words(&(r[2]),a,n,b[2]);
  1079. if (--n <= 0) return;
  1080. bn_mul_add_words(&(r[3]),a,n,b[3]);
  1081. if (--n <= 0) return;
  1082. bn_mul_add_words(&(r[4]),a,n,b[4]);
  1083. r+=4;
  1084. b+=4;
  1085. }
  1086. }