16a599222SSimon L. B. Nielsen #include "../bn_lcl.h" 2ed5d4f9aSSimon L. B. Nielsen #ifdef __SUNPRO_C 3ed5d4f9aSSimon L. B. Nielsen # include "../bn_asm.c" /* kind of dirty hack for Sun Studio */ 4ed5d4f9aSSimon L. B. Nielsen #else 55c87c606SMark Murray /* 65c87c606SMark Murray * x86_64 BIGNUM accelerator version 0.1, December 2002. 75c87c606SMark Murray * 85c87c606SMark Murray * Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL 95c87c606SMark Murray * project. 105c87c606SMark Murray * 115c87c606SMark Murray * Rights for redistribution and usage in source and binary forms are 125c87c606SMark Murray * granted according to the OpenSSL license. Warranty of any kind is 135c87c606SMark Murray * disclaimed. 145c87c606SMark Murray * 155c87c606SMark Murray * Q. Version 0.1? It doesn't sound like Andy, he used to assign real 165c87c606SMark Murray * versions, like 1.0... 175c87c606SMark Murray * A. Well, that's because this code is basically a quick-n-dirty 185c87c606SMark Murray * proof-of-concept hack. As you can see it's implemented with 195c87c606SMark Murray * inline assembler, which means that you're bound to GCC and that 203b4e3dcbSSimon L. B. Nielsen * there might be enough room for further improvement. 215c87c606SMark Murray * 225c87c606SMark Murray * Q. Why inline assembler? 233b4e3dcbSSimon L. B. Nielsen * A. x86_64 features own ABI which I'm not familiar with. This is 243b4e3dcbSSimon L. B. Nielsen * why I decided to let the compiler take care of subroutine 253b4e3dcbSSimon L. B. Nielsen * prologue/epilogue as well as register allocation. For reference. 263b4e3dcbSSimon L. B. Nielsen * Win64 implements different ABI for AMD64, different from Linux. 275c87c606SMark Murray * 285c87c606SMark Murray * Q. How much faster does it get? 293b4e3dcbSSimon L. B. Nielsen * A. 'apps/openssl speed rsa dsa' output with no-asm: 303b4e3dcbSSimon L. B. Nielsen * 313b4e3dcbSSimon L. B. Nielsen * sign verify sign/s verify/s 323b4e3dcbSSimon L. B. Nielsen * rsa 512 bits 0.0006s 0.0001s 1683.8 18456.2 333b4e3dcbSSimon L. B. Nielsen * rsa 1024 bits 0.0028s 0.0002s 356.0 6407.0 343b4e3dcbSSimon L. B. Nielsen * rsa 2048 bits 0.0172s 0.0005s 58.0 1957.8 353b4e3dcbSSimon L. B. Nielsen * rsa 4096 bits 0.1155s 0.0018s 8.7 555.6 363b4e3dcbSSimon L. B. Nielsen * sign verify sign/s verify/s 373b4e3dcbSSimon L. B. Nielsen * dsa 512 bits 0.0005s 0.0006s 2100.8 1768.3 383b4e3dcbSSimon L. B. Nielsen * dsa 1024 bits 0.0014s 0.0018s 692.3 559.2 393b4e3dcbSSimon L. B. Nielsen * dsa 2048 bits 0.0049s 0.0061s 204.7 165.0 403b4e3dcbSSimon L. B. Nielsen * 413b4e3dcbSSimon L. B. Nielsen * 'apps/openssl speed rsa dsa' output with this module: 423b4e3dcbSSimon L. B. Nielsen * 433b4e3dcbSSimon L. B. Nielsen * sign verify sign/s verify/s 443b4e3dcbSSimon L. B. Nielsen * rsa 512 bits 0.0004s 0.0000s 2767.1 33297.9 453b4e3dcbSSimon L. B. Nielsen * rsa 1024 bits 0.0012s 0.0001s 867.4 14674.7 463b4e3dcbSSimon L. B. Nielsen * rsa 2048 bits 0.0061s 0.0002s 164.0 5270.0 473b4e3dcbSSimon L. B. Nielsen * rsa 4096 bits 0.0384s 0.0006s 26.1 1650.8 483b4e3dcbSSimon L. B. Nielsen * sign verify sign/s verify/s 493b4e3dcbSSimon L. B. Nielsen * dsa 512 bits 0.0002s 0.0003s 4442.2 3786.3 503b4e3dcbSSimon L. B. Nielsen * dsa 1024 bits 0.0005s 0.0007s 1835.1 1497.4 513b4e3dcbSSimon L. B. Nielsen * dsa 2048 bits 0.0016s 0.0020s 620.4 504.6 523b4e3dcbSSimon L. B. Nielsen * 533b4e3dcbSSimon L. B. Nielsen * For the reference. IA-32 assembler implementation performs 543b4e3dcbSSimon L. B. Nielsen * very much like 64-bit code compiled with no-asm on the same 553b4e3dcbSSimon L. B. Nielsen * machine. 565c87c606SMark Murray */ 575c87c606SMark Murray 585c87c606SMark Murray #define BN_ULONG unsigned long 595c87c606SMark Murray 606a599222SSimon L. B. Nielsen #undef mul 616a599222SSimon L. B. Nielsen #undef mul_add 626a599222SSimon L. B. Nielsen 635c87c606SMark Murray /* 645c87c606SMark Murray * "m"(a), "+m"(r) is the way to favor DirectPath �-code; 655c87c606SMark Murray * "g"(0) let the compiler to decide where does it 665c87c606SMark Murray * want to keep the value of zero; 675c87c606SMark Murray */ 685c87c606SMark Murray #define mul_add(r,a,word,carry) do { \ 695c87c606SMark Murray register BN_ULONG high,low; \ 705c87c606SMark Murray asm ("mulq %3" \ 715c87c606SMark Murray : "=a"(low),"=d"(high) \ 725c87c606SMark Murray : "a"(word),"m"(a) \ 735c87c606SMark Murray : "cc"); \ 745c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 755c87c606SMark Murray : "+r"(carry),"+d"(high)\ 765c87c606SMark Murray : "a"(low),"g"(0) \ 775c87c606SMark Murray : "cc"); \ 785c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 795c87c606SMark Murray : "+m"(r),"+d"(high) \ 805c87c606SMark Murray : "r"(carry),"g"(0) \ 815c87c606SMark Murray : "cc"); \ 825c87c606SMark Murray carry=high; \ 835c87c606SMark Murray } while (0) 845c87c606SMark Murray 855c87c606SMark Murray #define mul(r,a,word,carry) do { \ 865c87c606SMark Murray register BN_ULONG high,low; \ 875c87c606SMark Murray asm ("mulq %3" \ 885c87c606SMark Murray : "=a"(low),"=d"(high) \ 895c87c606SMark Murray : "a"(word),"g"(a) \ 905c87c606SMark Murray : "cc"); \ 915c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 925c87c606SMark Murray : "+r"(carry),"+d"(high)\ 935c87c606SMark Murray : "a"(low),"g"(0) \ 945c87c606SMark Murray : "cc"); \ 955c87c606SMark Murray (r)=carry, carry=high; \ 965c87c606SMark Murray } while (0) 975c87c606SMark Murray 985c87c606SMark Murray #define sqr(r0,r1,a) \ 995c87c606SMark Murray asm ("mulq %2" \ 1005c87c606SMark Murray : "=a"(r0),"=d"(r1) \ 1015c87c606SMark Murray : "a"(a) \ 1025c87c606SMark Murray : "cc"); 1035c87c606SMark Murray 1046a599222SSimon L. B. Nielsen BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) 1055c87c606SMark Murray { 1065c87c606SMark Murray BN_ULONG c1=0; 1075c87c606SMark Murray 1085c87c606SMark Murray if (num <= 0) return(c1); 1095c87c606SMark Murray 1105c87c606SMark Murray while (num&~3) 1115c87c606SMark Murray { 1125c87c606SMark Murray mul_add(rp[0],ap[0],w,c1); 1135c87c606SMark Murray mul_add(rp[1],ap[1],w,c1); 1145c87c606SMark Murray mul_add(rp[2],ap[2],w,c1); 1155c87c606SMark Murray mul_add(rp[3],ap[3],w,c1); 1165c87c606SMark Murray ap+=4; rp+=4; num-=4; 1175c87c606SMark Murray } 1185c87c606SMark Murray if (num) 1195c87c606SMark Murray { 1205c87c606SMark Murray mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1; 1215c87c606SMark Murray mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1; 1225c87c606SMark Murray mul_add(rp[2],ap[2],w,c1); return c1; 1235c87c606SMark Murray } 1245c87c606SMark Murray 1255c87c606SMark Murray return(c1); 1265c87c606SMark Murray } 1275c87c606SMark Murray 1286a599222SSimon L. B. Nielsen BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) 1295c87c606SMark Murray { 1305c87c606SMark Murray BN_ULONG c1=0; 1315c87c606SMark Murray 1325c87c606SMark Murray if (num <= 0) return(c1); 1335c87c606SMark Murray 1345c87c606SMark Murray while (num&~3) 1355c87c606SMark Murray { 1365c87c606SMark Murray mul(rp[0],ap[0],w,c1); 1375c87c606SMark Murray mul(rp[1],ap[1],w,c1); 1385c87c606SMark Murray mul(rp[2],ap[2],w,c1); 1395c87c606SMark Murray mul(rp[3],ap[3],w,c1); 1405c87c606SMark Murray ap+=4; rp+=4; num-=4; 1415c87c606SMark Murray } 1425c87c606SMark Murray if (num) 1435c87c606SMark Murray { 1445c87c606SMark Murray mul(rp[0],ap[0],w,c1); if (--num == 0) return c1; 1455c87c606SMark Murray mul(rp[1],ap[1],w,c1); if (--num == 0) return c1; 1465c87c606SMark Murray mul(rp[2],ap[2],w,c1); 1475c87c606SMark Murray } 1485c87c606SMark Murray return(c1); 1495c87c606SMark Murray } 1505c87c606SMark Murray 1516a599222SSimon L. B. Nielsen void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) 1525c87c606SMark Murray { 1535c87c606SMark Murray if (n <= 0) return; 1545c87c606SMark Murray 1555c87c606SMark Murray while (n&~3) 1565c87c606SMark Murray { 1575c87c606SMark Murray sqr(r[0],r[1],a[0]); 1585c87c606SMark Murray sqr(r[2],r[3],a[1]); 1595c87c606SMark Murray sqr(r[4],r[5],a[2]); 1605c87c606SMark Murray sqr(r[6],r[7],a[3]); 1615c87c606SMark Murray a+=4; r+=8; n-=4; 1625c87c606SMark Murray } 1635c87c606SMark Murray if (n) 1645c87c606SMark Murray { 1655c87c606SMark Murray sqr(r[0],r[1],a[0]); if (--n == 0) return; 1665c87c606SMark Murray sqr(r[2],r[3],a[1]); if (--n == 0) return; 1675c87c606SMark Murray sqr(r[4],r[5],a[2]); 1685c87c606SMark Murray } 1695c87c606SMark Murray } 1705c87c606SMark Murray 1715c87c606SMark Murray BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) 1725c87c606SMark Murray { BN_ULONG ret,waste; 1735c87c606SMark Murray 174ced566fdSJacques Vidrine asm ("divq %4" 1755c87c606SMark Murray : "=a"(ret),"=d"(waste) 1765c87c606SMark Murray : "a"(l),"d"(h),"g"(d) 1775c87c606SMark Murray : "cc"); 1785c87c606SMark Murray 1795c87c606SMark Murray return ret; 1805c87c606SMark Murray } 1815c87c606SMark Murray 1826a599222SSimon L. B. Nielsen BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n) 1833b4e3dcbSSimon L. B. Nielsen { BN_ULONG ret=0,i=0; 1845c87c606SMark Murray 1855c87c606SMark Murray if (n <= 0) return 0; 1865c87c606SMark Murray 1875c87c606SMark Murray asm ( 1885c87c606SMark Murray " subq %2,%2 \n" 1895c87c606SMark Murray ".align 16 \n" 1905c87c606SMark Murray "1: movq (%4,%2,8),%0 \n" 1915c87c606SMark Murray " adcq (%5,%2,8),%0 \n" 1925c87c606SMark Murray " movq %0,(%3,%2,8) \n" 1935c87c606SMark Murray " leaq 1(%2),%2 \n" 1945c87c606SMark Murray " loop 1b \n" 1955c87c606SMark Murray " sbbq %0,%0 \n" 1963b4e3dcbSSimon L. B. Nielsen : "=&a"(ret),"+c"(n),"=&r"(i) 1975c87c606SMark Murray : "r"(rp),"r"(ap),"r"(bp) 1985c87c606SMark Murray : "cc" 1995c87c606SMark Murray ); 2005c87c606SMark Murray 2015c87c606SMark Murray return ret&1; 2025c87c606SMark Murray } 2035c87c606SMark Murray 2045c87c606SMark Murray #ifndef SIMICS 2056a599222SSimon L. B. Nielsen BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int n) 2063b4e3dcbSSimon L. B. Nielsen { BN_ULONG ret=0,i=0; 2075c87c606SMark Murray 2085c87c606SMark Murray if (n <= 0) return 0; 2095c87c606SMark Murray 2105c87c606SMark Murray asm ( 2115c87c606SMark Murray " subq %2,%2 \n" 2125c87c606SMark Murray ".align 16 \n" 2135c87c606SMark Murray "1: movq (%4,%2,8),%0 \n" 2145c87c606SMark Murray " sbbq (%5,%2,8),%0 \n" 2155c87c606SMark Murray " movq %0,(%3,%2,8) \n" 2165c87c606SMark Murray " leaq 1(%2),%2 \n" 2175c87c606SMark Murray " loop 1b \n" 2185c87c606SMark Murray " sbbq %0,%0 \n" 2193b4e3dcbSSimon L. B. Nielsen : "=&a"(ret),"+c"(n),"=&r"(i) 2205c87c606SMark Murray : "r"(rp),"r"(ap),"r"(bp) 2215c87c606SMark Murray : "cc" 2225c87c606SMark Murray ); 2235c87c606SMark Murray 2245c87c606SMark Murray return ret&1; 2255c87c606SMark Murray } 2265c87c606SMark Murray #else 2275c87c606SMark Murray /* Simics 1.4<7 has buggy sbbq:-( */ 2285c87c606SMark Murray #define BN_MASK2 0xffffffffffffffffL 2295c87c606SMark Murray BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) 2305c87c606SMark Murray { 2315c87c606SMark Murray BN_ULONG t1,t2; 2325c87c606SMark Murray int c=0; 2335c87c606SMark Murray 2345c87c606SMark Murray if (n <= 0) return((BN_ULONG)0); 2355c87c606SMark Murray 2365c87c606SMark Murray for (;;) 2375c87c606SMark Murray { 2385c87c606SMark Murray t1=a[0]; t2=b[0]; 2395c87c606SMark Murray r[0]=(t1-t2-c)&BN_MASK2; 2405c87c606SMark Murray if (t1 != t2) c=(t1 < t2); 2415c87c606SMark Murray if (--n <= 0) break; 2425c87c606SMark Murray 2435c87c606SMark Murray t1=a[1]; t2=b[1]; 2445c87c606SMark Murray r[1]=(t1-t2-c)&BN_MASK2; 2455c87c606SMark Murray if (t1 != t2) c=(t1 < t2); 2465c87c606SMark Murray if (--n <= 0) break; 2475c87c606SMark Murray 2485c87c606SMark Murray t1=a[2]; t2=b[2]; 2495c87c606SMark Murray r[2]=(t1-t2-c)&BN_MASK2; 2505c87c606SMark Murray if (t1 != t2) c=(t1 < t2); 2515c87c606SMark Murray if (--n <= 0) break; 2525c87c606SMark Murray 2535c87c606SMark Murray t1=a[3]; t2=b[3]; 2545c87c606SMark Murray r[3]=(t1-t2-c)&BN_MASK2; 2555c87c606SMark Murray if (t1 != t2) c=(t1 < t2); 2565c87c606SMark Murray if (--n <= 0) break; 2575c87c606SMark Murray 2585c87c606SMark Murray a+=4; 2595c87c606SMark Murray b+=4; 2605c87c606SMark Murray r+=4; 2615c87c606SMark Murray } 2625c87c606SMark Murray return(c); 2635c87c606SMark Murray } 2645c87c606SMark Murray #endif 2655c87c606SMark Murray 2665c87c606SMark Murray /* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ 2675c87c606SMark Murray /* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ 2685c87c606SMark Murray /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ 2695c87c606SMark Murray /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ 2705c87c606SMark Murray 2715c87c606SMark Murray #if 0 2725c87c606SMark Murray /* original macros are kept for reference purposes */ 2735c87c606SMark Murray #define mul_add_c(a,b,c0,c1,c2) { \ 2745c87c606SMark Murray BN_ULONG ta=(a),tb=(b); \ 2755c87c606SMark Murray t1 = ta * tb; \ 2765c87c606SMark Murray t2 = BN_UMULT_HIGH(ta,tb); \ 2775c87c606SMark Murray c0 += t1; t2 += (c0<t1)?1:0; \ 2785c87c606SMark Murray c1 += t2; c2 += (c1<t2)?1:0; \ 2795c87c606SMark Murray } 2805c87c606SMark Murray 2815c87c606SMark Murray #define mul_add_c2(a,b,c0,c1,c2) { \ 2825c87c606SMark Murray BN_ULONG ta=(a),tb=(b),t0; \ 2835c87c606SMark Murray t1 = BN_UMULT_HIGH(ta,tb); \ 2845c87c606SMark Murray t0 = ta * tb; \ 2855c87c606SMark Murray t2 = t1+t1; c2 += (t2<t1)?1:0; \ 2865c87c606SMark Murray t1 = t0+t0; t2 += (t1<t0)?1:0; \ 2875c87c606SMark Murray c0 += t1; t2 += (c0<t1)?1:0; \ 2885c87c606SMark Murray c1 += t2; c2 += (c1<t2)?1:0; \ 2895c87c606SMark Murray } 2905c87c606SMark Murray #else 2915c87c606SMark Murray #define mul_add_c(a,b,c0,c1,c2) do { \ 2925c87c606SMark Murray asm ("mulq %3" \ 2935c87c606SMark Murray : "=a"(t1),"=d"(t2) \ 2945c87c606SMark Murray : "a"(a),"m"(b) \ 2955c87c606SMark Murray : "cc"); \ 2965c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 2975c87c606SMark Murray : "+r"(c0),"+d"(t2) \ 2985c87c606SMark Murray : "a"(t1),"g"(0) \ 2995c87c606SMark Murray : "cc"); \ 3005c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 3015c87c606SMark Murray : "+r"(c1),"+r"(c2) \ 3025c87c606SMark Murray : "d"(t2),"g"(0) \ 3035c87c606SMark Murray : "cc"); \ 3045c87c606SMark Murray } while (0) 3055c87c606SMark Murray 3065c87c606SMark Murray #define sqr_add_c(a,i,c0,c1,c2) do { \ 3075c87c606SMark Murray asm ("mulq %2" \ 3085c87c606SMark Murray : "=a"(t1),"=d"(t2) \ 3095c87c606SMark Murray : "a"(a[i]) \ 3105c87c606SMark Murray : "cc"); \ 3115c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 3125c87c606SMark Murray : "+r"(c0),"+d"(t2) \ 3135c87c606SMark Murray : "a"(t1),"g"(0) \ 3145c87c606SMark Murray : "cc"); \ 3155c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 3165c87c606SMark Murray : "+r"(c1),"+r"(c2) \ 3175c87c606SMark Murray : "d"(t2),"g"(0) \ 3185c87c606SMark Murray : "cc"); \ 3195c87c606SMark Murray } while (0) 3205c87c606SMark Murray 3215c87c606SMark Murray #define mul_add_c2(a,b,c0,c1,c2) do { \ 3225c87c606SMark Murray asm ("mulq %3" \ 3235c87c606SMark Murray : "=a"(t1),"=d"(t2) \ 3245c87c606SMark Murray : "a"(a),"m"(b) \ 3255c87c606SMark Murray : "cc"); \ 3265c87c606SMark Murray asm ("addq %0,%0; adcq %2,%1" \ 3275c87c606SMark Murray : "+d"(t2),"+r"(c2) \ 3285c87c606SMark Murray : "g"(0) \ 3295c87c606SMark Murray : "cc"); \ 3305c87c606SMark Murray asm ("addq %0,%0; adcq %2,%1" \ 3315c87c606SMark Murray : "+a"(t1),"+d"(t2) \ 3325c87c606SMark Murray : "g"(0) \ 3335c87c606SMark Murray : "cc"); \ 3345c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 3355c87c606SMark Murray : "+r"(c0),"+d"(t2) \ 3365c87c606SMark Murray : "a"(t1),"g"(0) \ 3375c87c606SMark Murray : "cc"); \ 3385c87c606SMark Murray asm ("addq %2,%0; adcq %3,%1" \ 3395c87c606SMark Murray : "+r"(c1),"+r"(c2) \ 3405c87c606SMark Murray : "d"(t2),"g"(0) \ 3415c87c606SMark Murray : "cc"); \ 3425c87c606SMark Murray } while (0) 3435c87c606SMark Murray #endif 3445c87c606SMark Murray 3455c87c606SMark Murray #define sqr_add_c2(a,i,j,c0,c1,c2) \ 3465c87c606SMark Murray mul_add_c2((a)[i],(a)[j],c0,c1,c2) 3475c87c606SMark Murray 3485c87c606SMark Murray void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) 3495c87c606SMark Murray { 3505c87c606SMark Murray BN_ULONG t1,t2; 3515c87c606SMark Murray BN_ULONG c1,c2,c3; 3525c87c606SMark Murray 3535c87c606SMark Murray c1=0; 3545c87c606SMark Murray c2=0; 3555c87c606SMark Murray c3=0; 3565c87c606SMark Murray mul_add_c(a[0],b[0],c1,c2,c3); 3575c87c606SMark Murray r[0]=c1; 3585c87c606SMark Murray c1=0; 3595c87c606SMark Murray mul_add_c(a[0],b[1],c2,c3,c1); 3605c87c606SMark Murray mul_add_c(a[1],b[0],c2,c3,c1); 3615c87c606SMark Murray r[1]=c2; 3625c87c606SMark Murray c2=0; 3635c87c606SMark Murray mul_add_c(a[2],b[0],c3,c1,c2); 3645c87c606SMark Murray mul_add_c(a[1],b[1],c3,c1,c2); 3655c87c606SMark Murray mul_add_c(a[0],b[2],c3,c1,c2); 3665c87c606SMark Murray r[2]=c3; 3675c87c606SMark Murray c3=0; 3685c87c606SMark Murray mul_add_c(a[0],b[3],c1,c2,c3); 3695c87c606SMark Murray mul_add_c(a[1],b[2],c1,c2,c3); 3705c87c606SMark Murray mul_add_c(a[2],b[1],c1,c2,c3); 3715c87c606SMark Murray mul_add_c(a[3],b[0],c1,c2,c3); 3725c87c606SMark Murray r[3]=c1; 3735c87c606SMark Murray c1=0; 3745c87c606SMark Murray mul_add_c(a[4],b[0],c2,c3,c1); 3755c87c606SMark Murray mul_add_c(a[3],b[1],c2,c3,c1); 3765c87c606SMark Murray mul_add_c(a[2],b[2],c2,c3,c1); 3775c87c606SMark Murray mul_add_c(a[1],b[3],c2,c3,c1); 3785c87c606SMark Murray mul_add_c(a[0],b[4],c2,c3,c1); 3795c87c606SMark Murray r[4]=c2; 3805c87c606SMark Murray c2=0; 3815c87c606SMark Murray mul_add_c(a[0],b[5],c3,c1,c2); 3825c87c606SMark Murray mul_add_c(a[1],b[4],c3,c1,c2); 3835c87c606SMark Murray mul_add_c(a[2],b[3],c3,c1,c2); 3845c87c606SMark Murray mul_add_c(a[3],b[2],c3,c1,c2); 3855c87c606SMark Murray mul_add_c(a[4],b[1],c3,c1,c2); 3865c87c606SMark Murray mul_add_c(a[5],b[0],c3,c1,c2); 3875c87c606SMark Murray r[5]=c3; 3885c87c606SMark Murray c3=0; 3895c87c606SMark Murray mul_add_c(a[6],b[0],c1,c2,c3); 3905c87c606SMark Murray mul_add_c(a[5],b[1],c1,c2,c3); 3915c87c606SMark Murray mul_add_c(a[4],b[2],c1,c2,c3); 3925c87c606SMark Murray mul_add_c(a[3],b[3],c1,c2,c3); 3935c87c606SMark Murray mul_add_c(a[2],b[4],c1,c2,c3); 3945c87c606SMark Murray mul_add_c(a[1],b[5],c1,c2,c3); 3955c87c606SMark Murray mul_add_c(a[0],b[6],c1,c2,c3); 3965c87c606SMark Murray r[6]=c1; 3975c87c606SMark Murray c1=0; 3985c87c606SMark Murray mul_add_c(a[0],b[7],c2,c3,c1); 3995c87c606SMark Murray mul_add_c(a[1],b[6],c2,c3,c1); 4005c87c606SMark Murray mul_add_c(a[2],b[5],c2,c3,c1); 4015c87c606SMark Murray mul_add_c(a[3],b[4],c2,c3,c1); 4025c87c606SMark Murray mul_add_c(a[4],b[3],c2,c3,c1); 4035c87c606SMark Murray mul_add_c(a[5],b[2],c2,c3,c1); 4045c87c606SMark Murray mul_add_c(a[6],b[1],c2,c3,c1); 4055c87c606SMark Murray mul_add_c(a[7],b[0],c2,c3,c1); 4065c87c606SMark Murray r[7]=c2; 4075c87c606SMark Murray c2=0; 4085c87c606SMark Murray mul_add_c(a[7],b[1],c3,c1,c2); 4095c87c606SMark Murray mul_add_c(a[6],b[2],c3,c1,c2); 4105c87c606SMark Murray mul_add_c(a[5],b[3],c3,c1,c2); 4115c87c606SMark Murray mul_add_c(a[4],b[4],c3,c1,c2); 4125c87c606SMark Murray mul_add_c(a[3],b[5],c3,c1,c2); 4135c87c606SMark Murray mul_add_c(a[2],b[6],c3,c1,c2); 4145c87c606SMark Murray mul_add_c(a[1],b[7],c3,c1,c2); 4155c87c606SMark Murray r[8]=c3; 4165c87c606SMark Murray c3=0; 4175c87c606SMark Murray mul_add_c(a[2],b[7],c1,c2,c3); 4185c87c606SMark Murray mul_add_c(a[3],b[6],c1,c2,c3); 4195c87c606SMark Murray mul_add_c(a[4],b[5],c1,c2,c3); 4205c87c606SMark Murray mul_add_c(a[5],b[4],c1,c2,c3); 4215c87c606SMark Murray mul_add_c(a[6],b[3],c1,c2,c3); 4225c87c606SMark Murray mul_add_c(a[7],b[2],c1,c2,c3); 4235c87c606SMark Murray r[9]=c1; 4245c87c606SMark Murray c1=0; 4255c87c606SMark Murray mul_add_c(a[7],b[3],c2,c3,c1); 4265c87c606SMark Murray mul_add_c(a[6],b[4],c2,c3,c1); 4275c87c606SMark Murray mul_add_c(a[5],b[5],c2,c3,c1); 4285c87c606SMark Murray mul_add_c(a[4],b[6],c2,c3,c1); 4295c87c606SMark Murray mul_add_c(a[3],b[7],c2,c3,c1); 4305c87c606SMark Murray r[10]=c2; 4315c87c606SMark Murray c2=0; 4325c87c606SMark Murray mul_add_c(a[4],b[7],c3,c1,c2); 4335c87c606SMark Murray mul_add_c(a[5],b[6],c3,c1,c2); 4345c87c606SMark Murray mul_add_c(a[6],b[5],c3,c1,c2); 4355c87c606SMark Murray mul_add_c(a[7],b[4],c3,c1,c2); 4365c87c606SMark Murray r[11]=c3; 4375c87c606SMark Murray c3=0; 4385c87c606SMark Murray mul_add_c(a[7],b[5],c1,c2,c3); 4395c87c606SMark Murray mul_add_c(a[6],b[6],c1,c2,c3); 4405c87c606SMark Murray mul_add_c(a[5],b[7],c1,c2,c3); 4415c87c606SMark Murray r[12]=c1; 4425c87c606SMark Murray c1=0; 4435c87c606SMark Murray mul_add_c(a[6],b[7],c2,c3,c1); 4445c87c606SMark Murray mul_add_c(a[7],b[6],c2,c3,c1); 4455c87c606SMark Murray r[13]=c2; 4465c87c606SMark Murray c2=0; 4475c87c606SMark Murray mul_add_c(a[7],b[7],c3,c1,c2); 4485c87c606SMark Murray r[14]=c3; 4495c87c606SMark Murray r[15]=c1; 4505c87c606SMark Murray } 4515c87c606SMark Murray 4525c87c606SMark Murray void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) 4535c87c606SMark Murray { 4545c87c606SMark Murray BN_ULONG t1,t2; 4555c87c606SMark Murray BN_ULONG c1,c2,c3; 4565c87c606SMark Murray 4575c87c606SMark Murray c1=0; 4585c87c606SMark Murray c2=0; 4595c87c606SMark Murray c3=0; 4605c87c606SMark Murray mul_add_c(a[0],b[0],c1,c2,c3); 4615c87c606SMark Murray r[0]=c1; 4625c87c606SMark Murray c1=0; 4635c87c606SMark Murray mul_add_c(a[0],b[1],c2,c3,c1); 4645c87c606SMark Murray mul_add_c(a[1],b[0],c2,c3,c1); 4655c87c606SMark Murray r[1]=c2; 4665c87c606SMark Murray c2=0; 4675c87c606SMark Murray mul_add_c(a[2],b[0],c3,c1,c2); 4685c87c606SMark Murray mul_add_c(a[1],b[1],c3,c1,c2); 4695c87c606SMark Murray mul_add_c(a[0],b[2],c3,c1,c2); 4705c87c606SMark Murray r[2]=c3; 4715c87c606SMark Murray c3=0; 4725c87c606SMark Murray mul_add_c(a[0],b[3],c1,c2,c3); 4735c87c606SMark Murray mul_add_c(a[1],b[2],c1,c2,c3); 4745c87c606SMark Murray mul_add_c(a[2],b[1],c1,c2,c3); 4755c87c606SMark Murray mul_add_c(a[3],b[0],c1,c2,c3); 4765c87c606SMark Murray r[3]=c1; 4775c87c606SMark Murray c1=0; 4785c87c606SMark Murray mul_add_c(a[3],b[1],c2,c3,c1); 4795c87c606SMark Murray mul_add_c(a[2],b[2],c2,c3,c1); 4805c87c606SMark Murray mul_add_c(a[1],b[3],c2,c3,c1); 4815c87c606SMark Murray r[4]=c2; 4825c87c606SMark Murray c2=0; 4835c87c606SMark Murray mul_add_c(a[2],b[3],c3,c1,c2); 4845c87c606SMark Murray mul_add_c(a[3],b[2],c3,c1,c2); 4855c87c606SMark Murray r[5]=c3; 4865c87c606SMark Murray c3=0; 4875c87c606SMark Murray mul_add_c(a[3],b[3],c1,c2,c3); 4885c87c606SMark Murray r[6]=c1; 4895c87c606SMark Murray r[7]=c2; 4905c87c606SMark Murray } 4915c87c606SMark Murray 4926a599222SSimon L. B. Nielsen void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) 4935c87c606SMark Murray { 4945c87c606SMark Murray BN_ULONG t1,t2; 4955c87c606SMark Murray BN_ULONG c1,c2,c3; 4965c87c606SMark Murray 4975c87c606SMark Murray c1=0; 4985c87c606SMark Murray c2=0; 4995c87c606SMark Murray c3=0; 5005c87c606SMark Murray sqr_add_c(a,0,c1,c2,c3); 5015c87c606SMark Murray r[0]=c1; 5025c87c606SMark Murray c1=0; 5035c87c606SMark Murray sqr_add_c2(a,1,0,c2,c3,c1); 5045c87c606SMark Murray r[1]=c2; 5055c87c606SMark Murray c2=0; 5065c87c606SMark Murray sqr_add_c(a,1,c3,c1,c2); 5075c87c606SMark Murray sqr_add_c2(a,2,0,c3,c1,c2); 5085c87c606SMark Murray r[2]=c3; 5095c87c606SMark Murray c3=0; 5105c87c606SMark Murray sqr_add_c2(a,3,0,c1,c2,c3); 5115c87c606SMark Murray sqr_add_c2(a,2,1,c1,c2,c3); 5125c87c606SMark Murray r[3]=c1; 5135c87c606SMark Murray c1=0; 5145c87c606SMark Murray sqr_add_c(a,2,c2,c3,c1); 5155c87c606SMark Murray sqr_add_c2(a,3,1,c2,c3,c1); 5165c87c606SMark Murray sqr_add_c2(a,4,0,c2,c3,c1); 5175c87c606SMark Murray r[4]=c2; 5185c87c606SMark Murray c2=0; 5195c87c606SMark Murray sqr_add_c2(a,5,0,c3,c1,c2); 5205c87c606SMark Murray sqr_add_c2(a,4,1,c3,c1,c2); 5215c87c606SMark Murray sqr_add_c2(a,3,2,c3,c1,c2); 5225c87c606SMark Murray r[5]=c3; 5235c87c606SMark Murray c3=0; 5245c87c606SMark Murray sqr_add_c(a,3,c1,c2,c3); 5255c87c606SMark Murray sqr_add_c2(a,4,2,c1,c2,c3); 5265c87c606SMark Murray sqr_add_c2(a,5,1,c1,c2,c3); 5275c87c606SMark Murray sqr_add_c2(a,6,0,c1,c2,c3); 5285c87c606SMark Murray r[6]=c1; 5295c87c606SMark Murray c1=0; 5305c87c606SMark Murray sqr_add_c2(a,7,0,c2,c3,c1); 5315c87c606SMark Murray sqr_add_c2(a,6,1,c2,c3,c1); 5325c87c606SMark Murray sqr_add_c2(a,5,2,c2,c3,c1); 5335c87c606SMark Murray sqr_add_c2(a,4,3,c2,c3,c1); 5345c87c606SMark Murray r[7]=c2; 5355c87c606SMark Murray c2=0; 5365c87c606SMark Murray sqr_add_c(a,4,c3,c1,c2); 5375c87c606SMark Murray sqr_add_c2(a,5,3,c3,c1,c2); 5385c87c606SMark Murray sqr_add_c2(a,6,2,c3,c1,c2); 5395c87c606SMark Murray sqr_add_c2(a,7,1,c3,c1,c2); 5405c87c606SMark Murray r[8]=c3; 5415c87c606SMark Murray c3=0; 5425c87c606SMark Murray sqr_add_c2(a,7,2,c1,c2,c3); 5435c87c606SMark Murray sqr_add_c2(a,6,3,c1,c2,c3); 5445c87c606SMark Murray sqr_add_c2(a,5,4,c1,c2,c3); 5455c87c606SMark Murray r[9]=c1; 5465c87c606SMark Murray c1=0; 5475c87c606SMark Murray sqr_add_c(a,5,c2,c3,c1); 5485c87c606SMark Murray sqr_add_c2(a,6,4,c2,c3,c1); 5495c87c606SMark Murray sqr_add_c2(a,7,3,c2,c3,c1); 5505c87c606SMark Murray r[10]=c2; 5515c87c606SMark Murray c2=0; 5525c87c606SMark Murray sqr_add_c2(a,7,4,c3,c1,c2); 5535c87c606SMark Murray sqr_add_c2(a,6,5,c3,c1,c2); 5545c87c606SMark Murray r[11]=c3; 5555c87c606SMark Murray c3=0; 5565c87c606SMark Murray sqr_add_c(a,6,c1,c2,c3); 5575c87c606SMark Murray sqr_add_c2(a,7,5,c1,c2,c3); 5585c87c606SMark Murray r[12]=c1; 5595c87c606SMark Murray c1=0; 5605c87c606SMark Murray sqr_add_c2(a,7,6,c2,c3,c1); 5615c87c606SMark Murray r[13]=c2; 5625c87c606SMark Murray c2=0; 5635c87c606SMark Murray sqr_add_c(a,7,c3,c1,c2); 5645c87c606SMark Murray r[14]=c3; 5655c87c606SMark Murray r[15]=c1; 5665c87c606SMark Murray } 5675c87c606SMark Murray 5686a599222SSimon L. B. Nielsen void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) 5695c87c606SMark Murray { 5705c87c606SMark Murray BN_ULONG t1,t2; 5715c87c606SMark Murray BN_ULONG c1,c2,c3; 5725c87c606SMark Murray 5735c87c606SMark Murray c1=0; 5745c87c606SMark Murray c2=0; 5755c87c606SMark Murray c3=0; 5765c87c606SMark Murray sqr_add_c(a,0,c1,c2,c3); 5775c87c606SMark Murray r[0]=c1; 5785c87c606SMark Murray c1=0; 5795c87c606SMark Murray sqr_add_c2(a,1,0,c2,c3,c1); 5805c87c606SMark Murray r[1]=c2; 5815c87c606SMark Murray c2=0; 5825c87c606SMark Murray sqr_add_c(a,1,c3,c1,c2); 5835c87c606SMark Murray sqr_add_c2(a,2,0,c3,c1,c2); 5845c87c606SMark Murray r[2]=c3; 5855c87c606SMark Murray c3=0; 5865c87c606SMark Murray sqr_add_c2(a,3,0,c1,c2,c3); 5875c87c606SMark Murray sqr_add_c2(a,2,1,c1,c2,c3); 5885c87c606SMark Murray r[3]=c1; 5895c87c606SMark Murray c1=0; 5905c87c606SMark Murray sqr_add_c(a,2,c2,c3,c1); 5915c87c606SMark Murray sqr_add_c2(a,3,1,c2,c3,c1); 5925c87c606SMark Murray r[4]=c2; 5935c87c606SMark Murray c2=0; 5945c87c606SMark Murray sqr_add_c2(a,3,2,c3,c1,c2); 5955c87c606SMark Murray r[5]=c3; 5965c87c606SMark Murray c3=0; 5975c87c606SMark Murray sqr_add_c(a,3,c1,c2,c3); 5985c87c606SMark Murray r[6]=c1; 5995c87c606SMark Murray r[7]=c2; 6005c87c606SMark Murray } 601ed5d4f9aSSimon L. B. Nielsen #endif 602