bn_asm.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:19k
源码类别:

其他游戏

开发平台:

Visual C++

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