bn_asm.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /* crypto/bn/bn_asm.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(BN_LLONG) || defined(BN_UMULT_HIGH)
  67. BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
  68. BN_ULONG w)
  69. {
  70. BN_ULONG c1 = 0;
  71. assert(num >= 0);
  72. if (num <= 0)
  73. return (c1);
  74. while (num & ~3) {
  75. mul_add(rp[0], ap[0], w, c1);
  76. mul_add(rp[1], ap[1], w, c1);
  77. mul_add(rp[2], ap[2], w, c1);
  78. mul_add(rp[3], ap[3], w, c1);
  79. ap += 4;
  80. rp += 4;
  81. num -= 4;
  82. }
  83. if (num) {
  84. mul_add(rp[0], ap[0], w, c1);
  85. if (--num == 0)
  86. return c1;
  87. mul_add(rp[1], ap[1], w, c1);
  88. if (--num == 0)
  89. return c1;
  90. mul_add(rp[2], ap[2], w, c1);
  91. return c1;
  92. }
  93. return (c1);
  94. }
  95. BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
  96. {
  97. BN_ULONG c1 = 0;
  98. assert(num >= 0);
  99. if (num <= 0)
  100. return (c1);
  101. while (num & ~3) {
  102. mul(rp[0], ap[0], w, c1);
  103. mul(rp[1], ap[1], w, c1);
  104. mul(rp[2], ap[2], w, c1);
  105. mul(rp[3], ap[3], w, c1);
  106. ap += 4;
  107. rp += 4;
  108. num -= 4;
  109. }
  110. if (num) {
  111. mul(rp[0], ap[0], w, c1);
  112. if (--num == 0)
  113. return c1;
  114. mul(rp[1], ap[1], w, c1);
  115. if (--num == 0)
  116. return c1;
  117. mul(rp[2], ap[2], w, c1);
  118. }
  119. return (c1);
  120. }
  121. void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
  122. {
  123. assert(n >= 0);
  124. if (n <= 0)
  125. return;
  126. while (n & ~3) {
  127. sqr(r[0], r[1], a[0]);
  128. sqr(r[2], r[3], a[1]);
  129. sqr(r[4], r[5], a[2]);
  130. sqr(r[6], r[7], a[3]);
  131. a += 4;
  132. r += 8;
  133. n -= 4;
  134. }
  135. if (n) {
  136. sqr(r[0], r[1], a[0]);
  137. if (--n == 0)
  138. return;
  139. sqr(r[2], r[3], a[1]);
  140. if (--n == 0)
  141. return;
  142. sqr(r[4], r[5], a[2]);
  143. }
  144. }
  145. #else /* !(defined(BN_LLONG) ||
  146. * defined(BN_UMULT_HIGH)) */
  147. BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
  148. BN_ULONG w)
  149. {
  150. BN_ULONG c = 0;
  151. BN_ULONG bl, bh;
  152. assert(num >= 0);
  153. if (num <= 0)
  154. return ((BN_ULONG)0);
  155. bl = LBITS(w);
  156. bh = HBITS(w);
  157. for (;;) {
  158. mul_add(rp[0], ap[0], bl, bh, c);
  159. if (--num == 0)
  160. break;
  161. mul_add(rp[1], ap[1], bl, bh, c);
  162. if (--num == 0)
  163. break;
  164. mul_add(rp[2], ap[2], bl, bh, c);
  165. if (--num == 0)
  166. break;
  167. mul_add(rp[3], ap[3], bl, bh, c);
  168. if (--num == 0)
  169. break;
  170. ap += 4;
  171. rp += 4;
  172. }
  173. return (c);
  174. }
  175. BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
  176. {
  177. BN_ULONG carry = 0;
  178. BN_ULONG bl, bh;
  179. assert(num >= 0);
  180. if (num <= 0)
  181. return ((BN_ULONG)0);
  182. bl = LBITS(w);
  183. bh = HBITS(w);
  184. for (;;) {
  185. mul(rp[0], ap[0], bl, bh, carry);
  186. if (--num == 0)
  187. break;
  188. mul(rp[1], ap[1], bl, bh, carry);
  189. if (--num == 0)
  190. break;
  191. mul(rp[2], ap[2], bl, bh, carry);
  192. if (--num == 0)
  193. break;
  194. mul(rp[3], ap[3], bl, bh, carry);
  195. if (--num == 0)
  196. break;
  197. ap += 4;
  198. rp += 4;
  199. }
  200. return (carry);
  201. }
  202. void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
  203. {
  204. assert(n >= 0);
  205. if (n <= 0)
  206. return;
  207. for (;;) {
  208. sqr64(r[0], r[1], a[0]);
  209. if (--n == 0)
  210. break;
  211. sqr64(r[2], r[3], a[1]);
  212. if (--n == 0)
  213. break;
  214. sqr64(r[4], r[5], a[2]);
  215. if (--n == 0)
  216. break;
  217. sqr64(r[6], r[7], a[3]);
  218. if (--n == 0)
  219. break;
  220. a += 4;
  221. r += 8;
  222. }
  223. }
  224. #endif /* !(defined(BN_LLONG) ||
  225. * defined(BN_UMULT_HIGH)) */
  226. #if defined(BN_LLONG) && defined(BN_DIV2W)
  227. BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
  228. {
  229. return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d));
  230. }
  231. #else
  232. /* Divide h,l by d and return the result. */
  233. /* I need to test this some more :-( */
  234. BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
  235. {
  236. BN_ULONG dh, dl, q, ret = 0, th, tl, t;
  237. int i, count = 2;
  238. if (d == 0)
  239. return (BN_MASK2);
  240. i = BN_num_bits_word(d);
  241. assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
  242. i = BN_BITS2 - i;
  243. if (h >= d)
  244. h -= d;
  245. if (i) {
  246. d <<= i;
  247. h = (h << i) | (l >> (BN_BITS2 - i));
  248. l <<= i;
  249. }
  250. dh = (d & BN_MASK2h) >> BN_BITS4;
  251. dl = (d & BN_MASK2l);
  252. for (;;) {
  253. if ((h >> BN_BITS4) == dh)
  254. q = BN_MASK2l;
  255. else
  256. q = h / dh;
  257. th = q * dh;
  258. tl = dl * q;
  259. for (;;) {
  260. t = h - th;
  261. if ((t & BN_MASK2h) ||
  262. ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4))))
  263. break;
  264. q--;
  265. th -= dh;
  266. tl -= dl;
  267. }
  268. t = (tl >> BN_BITS4);
  269. tl = (tl << BN_BITS4) & BN_MASK2h;
  270. th += t;
  271. if (l < tl)
  272. th++;
  273. l -= tl;
  274. if (h < th) {
  275. h += d;
  276. q--;
  277. }
  278. h -= th;
  279. if (--count == 0)
  280. break;
  281. ret = q << BN_BITS4;
  282. h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
  283. l = (l & BN_MASK2l) << BN_BITS4;
  284. }
  285. ret |= q;
  286. return (ret);
  287. }
  288. #endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
  289. #ifdef BN_LLONG
  290. BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
  291. int n)
  292. {
  293. BN_ULLONG ll = 0;
  294. assert(n >= 0);
  295. if (n <= 0)
  296. return ((BN_ULONG)0);
  297. for (;;) {
  298. ll += (BN_ULLONG) a[0] + b[0];
  299. r[0] = (BN_ULONG)ll & BN_MASK2;
  300. ll >>= BN_BITS2;
  301. if (--n <= 0)
  302. break;
  303. ll += (BN_ULLONG) a[1] + b[1];
  304. r[1] = (BN_ULONG)ll & BN_MASK2;
  305. ll >>= BN_BITS2;
  306. if (--n <= 0)
  307. break;
  308. ll += (BN_ULLONG) a[2] + b[2];
  309. r[2] = (BN_ULONG)ll & BN_MASK2;
  310. ll >>= BN_BITS2;
  311. if (--n <= 0)
  312. break;
  313. ll += (BN_ULLONG) a[3] + b[3];
  314. r[3] = (BN_ULONG)ll & BN_MASK2;
  315. ll >>= BN_BITS2;
  316. if (--n <= 0)
  317. break;
  318. a += 4;
  319. b += 4;
  320. r += 4;
  321. }
  322. return ((BN_ULONG)ll);
  323. }
  324. #else /* !BN_LLONG */
  325. BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
  326. int n)
  327. {
  328. BN_ULONG c, l, t;
  329. assert(n >= 0);
  330. if (n <= 0)
  331. return ((BN_ULONG)0);
  332. c = 0;
  333. for (;;) {
  334. t = a[0];
  335. t = (t + c) & BN_MASK2;
  336. c = (t < c);
  337. l = (t + b[0]) & BN_MASK2;
  338. c += (l < t);
  339. r[0] = l;
  340. if (--n <= 0)
  341. break;
  342. t = a[1];
  343. t = (t + c) & BN_MASK2;
  344. c = (t < c);
  345. l = (t + b[1]) & BN_MASK2;
  346. c += (l < t);
  347. r[1] = l;
  348. if (--n <= 0)
  349. break;
  350. t = a[2];
  351. t = (t + c) & BN_MASK2;
  352. c = (t < c);
  353. l = (t + b[2]) & BN_MASK2;
  354. c += (l < t);
  355. r[2] = l;
  356. if (--n <= 0)
  357. break;
  358. t = a[3];
  359. t = (t + c) & BN_MASK2;
  360. c = (t < c);
  361. l = (t + b[3]) & BN_MASK2;
  362. c += (l < t);
  363. r[3] = l;
  364. if (--n <= 0)
  365. break;
  366. a += 4;
  367. b += 4;
  368. r += 4;
  369. }
  370. return ((BN_ULONG)c);
  371. }
  372. #endif /* !BN_LLONG */
  373. BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
  374. int n)
  375. {
  376. BN_ULONG t1, t2;
  377. int c = 0;
  378. assert(n >= 0);
  379. if (n <= 0)
  380. return ((BN_ULONG)0);
  381. for (;;) {
  382. t1 = a[0];
  383. t2 = b[0];
  384. r[0] = (t1 - t2 - c) & BN_MASK2;
  385. if (t1 != t2)
  386. c = (t1 < t2);
  387. if (--n <= 0)
  388. break;
  389. t1 = a[1];
  390. t2 = b[1];
  391. r[1] = (t1 - t2 - c) & BN_MASK2;
  392. if (t1 != t2)
  393. c = (t1 < t2);
  394. if (--n <= 0)
  395. break;
  396. t1 = a[2];
  397. t2 = b[2];
  398. r[2] = (t1 - t2 - c) & BN_MASK2;
  399. if (t1 != t2)
  400. c = (t1 < t2);
  401. if (--n <= 0)
  402. break;
  403. t1 = a[3];
  404. t2 = b[3];
  405. r[3] = (t1 - t2 - c) & BN_MASK2;
  406. if (t1 != t2)
  407. c = (t1 < t2);
  408. if (--n <= 0)
  409. break;
  410. a += 4;
  411. b += 4;
  412. r += 4;
  413. }
  414. return (c);
  415. }
  416. #ifdef BN_MUL_COMBA
  417. # undef bn_mul_comba8
  418. # undef bn_mul_comba4
  419. # undef bn_sqr_comba8
  420. # undef bn_sqr_comba4
  421. /* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */
  422. /* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
  423. /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
  424. /*
  425. * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number
  426. * c=(c2,c1,c0)
  427. */
  428. /*
  429. * Keep in mind that carrying into high part of multiplication result
  430. * can not overflow, because it cannot be all-ones.
  431. */
  432. # ifdef BN_LLONG
  433. # define mul_add_c(a,b,c0,c1,c2) \
  434. t=(BN_ULLONG)a*b; \
  435. t1=(BN_ULONG)Lw(t); \
  436. t2=(BN_ULONG)Hw(t); \
  437. c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
  438. c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
  439. # define mul_add_c2(a,b,c0,c1,c2) \
  440. t=(BN_ULLONG)a*b; \
  441. tt=(t+t)&BN_MASK; \
  442. if (tt < t) c2++; \
  443. t1=(BN_ULONG)Lw(tt); \
  444. t2=(BN_ULONG)Hw(tt); \
  445. c0=(c0+t1)&BN_MASK2; \
  446. if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
  447. c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
  448. # define sqr_add_c(a,i,c0,c1,c2) \
  449. t=(BN_ULLONG)a[i]*a[i]; \
  450. t1=(BN_ULONG)Lw(t); \
  451. t2=(BN_ULONG)Hw(t); \
  452. c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
  453. c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
  454. # define sqr_add_c2(a,i,j,c0,c1,c2) \
  455. mul_add_c2((a)[i],(a)[j],c0,c1,c2)
  456. # elif defined(BN_UMULT_LOHI)
  457. # define mul_add_c(a,b,c0,c1,c2) { \
  458. BN_ULONG ta=(a),tb=(b); \
  459. BN_UMULT_LOHI(t1,t2,ta,tb); \
  460. c0 += t1; t2 += (c0<t1)?1:0; \
  461. c1 += t2; c2 += (c1<t2)?1:0; \
  462. }
  463. # define mul_add_c2(a,b,c0,c1,c2) { \
  464. BN_ULONG ta=(a),tb=(b),t0; \
  465. BN_UMULT_LOHI(t0,t1,ta,tb); \
  466. c0 += t0; t2 = t1+((c0<t0)?1:0);\
  467. c1 += t2; c2 += (c1<t2)?1:0; \
  468. c0 += t0; t1 += (c0<t0)?1:0; \
  469. c1 += t1; c2 += (c1<t1)?1:0; \
  470. }
  471. # define sqr_add_c(a,i,c0,c1,c2) { \
  472. BN_ULONG ta=(a)[i]; \
  473. BN_UMULT_LOHI(t1,t2,ta,ta); \
  474. c0 += t1; t2 += (c0<t1)?1:0; \
  475. c1 += t2; c2 += (c1<t2)?1:0; \
  476. }
  477. # define sqr_add_c2(a,i,j,c0,c1,c2) \
  478. mul_add_c2((a)[i],(a)[j],c0,c1,c2)
  479. # elif defined(BN_UMULT_HIGH)
  480. # define mul_add_c(a,b,c0,c1,c2) { \
  481. BN_ULONG ta=(a),tb=(b); \
  482. t1 = ta * tb; \
  483. t2 = BN_UMULT_HIGH(ta,tb); \
  484. c0 += t1; t2 += (c0<t1)?1:0; \
  485. c1 += t2; c2 += (c1<t2)?1:0; \
  486. }
  487. # define mul_add_c2(a,b,c0,c1,c2) { \
  488. BN_ULONG ta=(a),tb=(b),t0; \
  489. t1 = BN_UMULT_HIGH(ta,tb); \
  490. t0 = ta * tb; \
  491. c0 += t0; t2 = t1+((c0<t0)?1:0);\
  492. c1 += t2; c2 += (c1<t2)?1:0; \
  493. c0 += t0; t1 += (c0<t0)?1:0; \
  494. c1 += t1; c2 += (c1<t1)?1:0; \
  495. }
  496. # define sqr_add_c(a,i,c0,c1,c2) { \
  497. BN_ULONG ta=(a)[i]; \
  498. t1 = ta * ta; \
  499. t2 = BN_UMULT_HIGH(ta,ta); \
  500. c0 += t1; t2 += (c0<t1)?1:0; \
  501. c1 += t2; c2 += (c1<t2)?1:0; \
  502. }
  503. # define sqr_add_c2(a,i,j,c0,c1,c2) \
  504. mul_add_c2((a)[i],(a)[j],c0,c1,c2)
  505. # else /* !BN_LLONG */
  506. # define mul_add_c(a,b,c0,c1,c2) \
  507. t1=LBITS(a); t2=HBITS(a); \
  508. bl=LBITS(b); bh=HBITS(b); \
  509. mul64(t1,t2,bl,bh); \
  510. c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
  511. c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
  512. # define mul_add_c2(a,b,c0,c1,c2) \
  513. t1=LBITS(a); t2=HBITS(a); \
  514. bl=LBITS(b); bh=HBITS(b); \
  515. mul64(t1,t2,bl,bh); \
  516. if (t2 & BN_TBIT) c2++; \
  517. t2=(t2+t2)&BN_MASK2; \
  518. if (t1 & BN_TBIT) t2++; \
  519. t1=(t1+t1)&BN_MASK2; \
  520. c0=(c0+t1)&BN_MASK2; \
  521. if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
  522. c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
  523. # define sqr_add_c(a,i,c0,c1,c2) \
  524. sqr64(t1,t2,(a)[i]); \
  525. c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
  526. c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
  527. # define sqr_add_c2(a,i,j,c0,c1,c2) \
  528. mul_add_c2((a)[i],(a)[j],c0,c1,c2)
  529. # endif /* !BN_LLONG */
  530. void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
  531. {
  532. # ifdef BN_LLONG
  533. BN_ULLONG t;
  534. # else
  535. BN_ULONG bl, bh;
  536. # endif
  537. BN_ULONG t1, t2;
  538. BN_ULONG c1, c2, c3;
  539. c1 = 0;
  540. c2 = 0;
  541. c3 = 0;
  542. mul_add_c(a[0], b[0], c1, c2, c3);
  543. r[0] = c1;
  544. c1 = 0;
  545. mul_add_c(a[0], b[1], c2, c3, c1);
  546. mul_add_c(a[1], b[0], c2, c3, c1);
  547. r[1] = c2;
  548. c2 = 0;
  549. mul_add_c(a[2], b[0], c3, c1, c2);
  550. mul_add_c(a[1], b[1], c3, c1, c2);
  551. mul_add_c(a[0], b[2], c3, c1, c2);
  552. r[2] = c3;
  553. c3 = 0;
  554. mul_add_c(a[0], b[3], c1, c2, c3);
  555. mul_add_c(a[1], b[2], c1, c2, c3);
  556. mul_add_c(a[2], b[1], c1, c2, c3);
  557. mul_add_c(a[3], b[0], c1, c2, c3);
  558. r[3] = c1;
  559. c1 = 0;
  560. mul_add_c(a[4], b[0], c2, c3, c1);
  561. mul_add_c(a[3], b[1], c2, c3, c1);
  562. mul_add_c(a[2], b[2], c2, c3, c1);
  563. mul_add_c(a[1], b[3], c2, c3, c1);
  564. mul_add_c(a[0], b[4], c2, c3, c1);
  565. r[4] = c2;
  566. c2 = 0;
  567. mul_add_c(a[0], b[5], c3, c1, c2);
  568. mul_add_c(a[1], b[4], c3, c1, c2);
  569. mul_add_c(a[2], b[3], c3, c1, c2);
  570. mul_add_c(a[3], b[2], c3, c1, c2);
  571. mul_add_c(a[4], b[1], c3, c1, c2);
  572. mul_add_c(a[5], b[0], c3, c1, c2);
  573. r[5] = c3;
  574. c3 = 0;
  575. mul_add_c(a[6], b[0], c1, c2, c3);
  576. mul_add_c(a[5], b[1], c1, c2, c3);
  577. mul_add_c(a[4], b[2], c1, c2, c3);
  578. mul_add_c(a[3], b[3], c1, c2, c3);
  579. mul_add_c(a[2], b[4], c1, c2, c3);
  580. mul_add_c(a[1], b[5], c1, c2, c3);
  581. mul_add_c(a[0], b[6], c1, c2, c3);
  582. r[6] = c1;
  583. c1 = 0;
  584. mul_add_c(a[0], b[7], c2, c3, c1);
  585. mul_add_c(a[1], b[6], c2, c3, c1);
  586. mul_add_c(a[2], b[5], c2, c3, c1);
  587. mul_add_c(a[3], b[4], c2, c3, c1);
  588. mul_add_c(a[4], b[3], c2, c3, c1);
  589. mul_add_c(a[5], b[2], c2, c3, c1);
  590. mul_add_c(a[6], b[1], c2, c3, c1);
  591. mul_add_c(a[7], b[0], c2, c3, c1);
  592. r[7] = c2;
  593. c2 = 0;
  594. mul_add_c(a[7], b[1], c3, c1, c2);
  595. mul_add_c(a[6], b[2], c3, c1, c2);
  596. mul_add_c(a[5], b[3], c3, c1, c2);
  597. mul_add_c(a[4], b[4], c3, c1, c2);
  598. mul_add_c(a[3], b[5], c3, c1, c2);
  599. mul_add_c(a[2], b[6], c3, c1, c2);
  600. mul_add_c(a[1], b[7], c3, c1, c2);
  601. r[8] = c3;
  602. c3 = 0;
  603. mul_add_c(a[2], b[7], c1, c2, c3);
  604. mul_add_c(a[3], b[6], c1, c2, c3);
  605. mul_add_c(a[4], b[5], c1, c2, c3);
  606. mul_add_c(a[5], b[4], c1, c2, c3);
  607. mul_add_c(a[6], b[3], c1, c2, c3);
  608. mul_add_c(a[7], b[2], c1, c2, c3);
  609. r[9] = c1;
  610. c1 = 0;
  611. mul_add_c(a[7], b[3], c2, c3, c1);
  612. mul_add_c(a[6], b[4], c2, c3, c1);
  613. mul_add_c(a[5], b[5], c2, c3, c1);
  614. mul_add_c(a[4], b[6], c2, c3, c1);
  615. mul_add_c(a[3], b[7], c2, c3, c1);
  616. r[10] = c2;
  617. c2 = 0;
  618. mul_add_c(a[4], b[7], c3, c1, c2);
  619. mul_add_c(a[5], b[6], c3, c1, c2);
  620. mul_add_c(a[6], b[5], c3, c1, c2);
  621. mul_add_c(a[7], b[4], c3, c1, c2);
  622. r[11] = c3;
  623. c3 = 0;
  624. mul_add_c(a[7], b[5], c1, c2, c3);
  625. mul_add_c(a[6], b[6], c1, c2, c3);
  626. mul_add_c(a[5], b[7], c1, c2, c3);
  627. r[12] = c1;
  628. c1 = 0;
  629. mul_add_c(a[6], b[7], c2, c3, c1);
  630. mul_add_c(a[7], b[6], c2, c3, c1);
  631. r[13] = c2;
  632. c2 = 0;
  633. mul_add_c(a[7], b[7], c3, c1, c2);
  634. r[14] = c3;
  635. r[15] = c1;
  636. }
  637. void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
  638. {
  639. # ifdef BN_LLONG
  640. BN_ULLONG t;
  641. # else
  642. BN_ULONG bl, bh;
  643. # endif
  644. BN_ULONG t1, t2;
  645. BN_ULONG c1, c2, c3;
  646. c1 = 0;
  647. c2 = 0;
  648. c3 = 0;
  649. mul_add_c(a[0], b[0], c1, c2, c3);
  650. r[0] = c1;
  651. c1 = 0;
  652. mul_add_c(a[0], b[1], c2, c3, c1);
  653. mul_add_c(a[1], b[0], c2, c3, c1);
  654. r[1] = c2;
  655. c2 = 0;
  656. mul_add_c(a[2], b[0], c3, c1, c2);
  657. mul_add_c(a[1], b[1], c3, c1, c2);
  658. mul_add_c(a[0], b[2], c3, c1, c2);
  659. r[2] = c3;
  660. c3 = 0;
  661. mul_add_c(a[0], b[3], c1, c2, c3);
  662. mul_add_c(a[1], b[2], c1, c2, c3);
  663. mul_add_c(a[2], b[1], c1, c2, c3);
  664. mul_add_c(a[3], b[0], c1, c2, c3);
  665. r[3] = c1;
  666. c1 = 0;
  667. mul_add_c(a[3], b[1], c2, c3, c1);
  668. mul_add_c(a[2], b[2], c2, c3, c1);
  669. mul_add_c(a[1], b[3], c2, c3, c1);
  670. r[4] = c2;
  671. c2 = 0;
  672. mul_add_c(a[2], b[3], c3, c1, c2);
  673. mul_add_c(a[3], b[2], c3, c1, c2);
  674. r[5] = c3;
  675. c3 = 0;
  676. mul_add_c(a[3], b[3], c1, c2, c3);
  677. r[6] = c1;
  678. r[7] = c2;
  679. }
  680. void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
  681. {
  682. # ifdef BN_LLONG
  683. BN_ULLONG t, tt;
  684. # else
  685. BN_ULONG bl, bh;
  686. # endif
  687. BN_ULONG t1, t2;
  688. BN_ULONG c1, c2, c3;
  689. c1 = 0;
  690. c2 = 0;
  691. c3 = 0;
  692. sqr_add_c(a, 0, c1, c2, c3);
  693. r[0] = c1;
  694. c1 = 0;
  695. sqr_add_c2(a, 1, 0, c2, c3, c1);
  696. r[1] = c2;
  697. c2 = 0;
  698. sqr_add_c(a, 1, c3, c1, c2);
  699. sqr_add_c2(a, 2, 0, c3, c1, c2);
  700. r[2] = c3;
  701. c3 = 0;
  702. sqr_add_c2(a, 3, 0, c1, c2, c3);
  703. sqr_add_c2(a, 2, 1, c1, c2, c3);
  704. r[3] = c1;
  705. c1 = 0;
  706. sqr_add_c(a, 2, c2, c3, c1);
  707. sqr_add_c2(a, 3, 1, c2, c3, c1);
  708. sqr_add_c2(a, 4, 0, c2, c3, c1);
  709. r[4] = c2;
  710. c2 = 0;
  711. sqr_add_c2(a, 5, 0, c3, c1, c2);
  712. sqr_add_c2(a, 4, 1, c3, c1, c2);
  713. sqr_add_c2(a, 3, 2, c3, c1, c2);
  714. r[5] = c3;
  715. c3 = 0;
  716. sqr_add_c(a, 3, c1, c2, c3);
  717. sqr_add_c2(a, 4, 2, c1, c2, c3);
  718. sqr_add_c2(a, 5, 1, c1, c2, c3);
  719. sqr_add_c2(a, 6, 0, c1, c2, c3);
  720. r[6] = c1;
  721. c1 = 0;
  722. sqr_add_c2(a, 7, 0, c2, c3, c1);
  723. sqr_add_c2(a, 6, 1, c2, c3, c1);
  724. sqr_add_c2(a, 5, 2, c2, c3, c1);
  725. sqr_add_c2(a, 4, 3, c2, c3, c1);
  726. r[7] = c2;
  727. c2 = 0;
  728. sqr_add_c(a, 4, c3, c1, c2);
  729. sqr_add_c2(a, 5, 3, c3, c1, c2);
  730. sqr_add_c2(a, 6, 2, c3, c1, c2);
  731. sqr_add_c2(a, 7, 1, c3, c1, c2);
  732. r[8] = c3;
  733. c3 = 0;
  734. sqr_add_c2(a, 7, 2, c1, c2, c3);
  735. sqr_add_c2(a, 6, 3, c1, c2, c3);
  736. sqr_add_c2(a, 5, 4, c1, c2, c3);
  737. r[9] = c1;
  738. c1 = 0;
  739. sqr_add_c(a, 5, c2, c3, c1);
  740. sqr_add_c2(a, 6, 4, c2, c3, c1);
  741. sqr_add_c2(a, 7, 3, c2, c3, c1);
  742. r[10] = c2;
  743. c2 = 0;
  744. sqr_add_c2(a, 7, 4, c3, c1, c2);
  745. sqr_add_c2(a, 6, 5, c3, c1, c2);
  746. r[11] = c3;
  747. c3 = 0;
  748. sqr_add_c(a, 6, c1, c2, c3);
  749. sqr_add_c2(a, 7, 5, c1, c2, c3);
  750. r[12] = c1;
  751. c1 = 0;
  752. sqr_add_c2(a, 7, 6, c2, c3, c1);
  753. r[13] = c2;
  754. c2 = 0;
  755. sqr_add_c(a, 7, c3, c1, c2);
  756. r[14] = c3;
  757. r[15] = c1;
  758. }
  759. void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
  760. {
  761. # ifdef BN_LLONG
  762. BN_ULLONG t, tt;
  763. # else
  764. BN_ULONG bl, bh;
  765. # endif
  766. BN_ULONG t1, t2;
  767. BN_ULONG c1, c2, c3;
  768. c1 = 0;
  769. c2 = 0;
  770. c3 = 0;
  771. sqr_add_c(a, 0, c1, c2, c3);
  772. r[0] = c1;
  773. c1 = 0;
  774. sqr_add_c2(a, 1, 0, c2, c3, c1);
  775. r[1] = c2;
  776. c2 = 0;
  777. sqr_add_c(a, 1, c3, c1, c2);
  778. sqr_add_c2(a, 2, 0, c3, c1, c2);
  779. r[2] = c3;
  780. c3 = 0;
  781. sqr_add_c2(a, 3, 0, c1, c2, c3);
  782. sqr_add_c2(a, 2, 1, c1, c2, c3);
  783. r[3] = c1;
  784. c1 = 0;
  785. sqr_add_c(a, 2, c2, c3, c1);
  786. sqr_add_c2(a, 3, 1, c2, c3, c1);
  787. r[4] = c2;
  788. c2 = 0;
  789. sqr_add_c2(a, 3, 2, c3, c1, c2);
  790. r[5] = c3;
  791. c3 = 0;
  792. sqr_add_c(a, 3, c1, c2, c3);
  793. r[6] = c1;
  794. r[7] = c2;
  795. }
  796. #else /* !BN_MUL_COMBA */
  797. /* hmm... is it faster just to do a multiply? */
  798. # undef bn_sqr_comba4
  799. void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
  800. {
  801. BN_ULONG t[8];
  802. bn_sqr_normal(r, a, 4, t);
  803. }
  804. # undef bn_sqr_comba8
  805. void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
  806. {
  807. BN_ULONG t[16];
  808. bn_sqr_normal(r, a, 8, t);
  809. }
  810. void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
  811. {
  812. r[4] = bn_mul_words(&(r[0]), a, 4, b[0]);
  813. r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]);
  814. r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]);
  815. r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]);
  816. }
  817. void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
  818. {
  819. r[8] = bn_mul_words(&(r[0]), a, 8, b[0]);
  820. r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]);
  821. r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]);
  822. r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]);
  823. r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]);
  824. r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]);
  825. r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]);
  826. r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]);
  827. }
  828. #endif /* !BN_MUL_COMBA */