Imported Upstream version 3.13.6
[platform/upstream/nss.git] / mozilla / security / nss / lib / freebl / mpi / mp_comba.c
1 /*
2  * The below file is derived from TFM v0.03.
3  * It contains code from fp_mul_comba.c and
4  * fp_sqr_comba.c, which contained the following license.
5  *
6  * Right now, the assembly in this file limits
7  * this code to AMD 64.
8  *
9  * This file is public domain.
10  */
11
12 /* TomsFastMath, a fast ISO C bignum library.
13  * 
14  * This project is meant to fill in where LibTomMath
15  * falls short.  That is speed ;-)
16  *
17  * This project is public domain and free for all purposes.
18  * 
19  * Tom St Denis, tomstdenis@iahu.ca
20  */
21
22
23 #include "mpi-priv.h"
24
25
26
27 /* clamp digits */
28 #define mp_clamp(a)   { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : ZPOS; }
29
30 /* anything you need at the start */
31 #define COMBA_START
32
33 /* clear the chaining variables */
34 #define COMBA_CLEAR \
35    c0 = c1 = c2 = 0;
36
37 /* forward the carry to the next digit */
38 #define COMBA_FORWARD \
39    do { c0 = c1; c1 = c2; c2 = 0; } while (0);
40
41 /* anything you need at the end */
42 #define COMBA_FINI
43
44 /* this should multiply i and j  */
45 #define MULADD(i, j)                                      \
46 __asm__  (                                                    \
47      "movq  %6,%%rax     \n\t"                            \
48      "mulq  %7           \n\t"                            \
49      "addq  %%rax,%0     \n\t"                            \
50      "adcq  %%rdx,%1     \n\t"                            \
51      "adcq  $0,%2        \n\t"                            \
52      :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j)  :"%rax","%rdx","cc");
53
54
55
56
57 /* sqr macros only */
58 #define CLEAR_CARRY \
59    c0 = c1 = c2 = 0;
60
61 #define COMBA_STORE(x) \
62    x = c0;
63
64 #define COMBA_STORE2(x) \
65    x = c1;
66
67 #define CARRY_FORWARD \
68    do { c0 = c1; c1 = c2; c2 = 0; } while (0);
69
70 #define COMBA_FINI
71
72 #define SQRADD(i, j)                                      \
73 __asm__ (                                                     \
74      "movq  %6,%%rax     \n\t"                            \
75      "mulq  %%rax        \n\t"                            \
76      "addq  %%rax,%0     \n\t"                            \
77      "adcq  %%rdx,%1     \n\t"                            \
78      "adcq  $0,%2        \n\t"                            \
79      :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","cc");
80
81 #define SQRADD2(i, j)                                     \
82 __asm__ (                                                     \
83      "movq  %6,%%rax     \n\t"                            \
84      "mulq  %7           \n\t"                            \
85      "addq  %%rax,%0     \n\t"                            \
86      "adcq  %%rdx,%1     \n\t"                            \
87      "adcq  $0,%2        \n\t"                            \
88      "addq  %%rax,%0     \n\t"                            \
89      "adcq  %%rdx,%1     \n\t"                            \
90      "adcq  $0,%2        \n\t"                            \
91      :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j)  :"%rax","%rdx","cc");
92
93 #define SQRADDSC(i, j)                                    \
94 __asm__ (                                                     \
95      "movq  %3,%%rax     \n\t"                            \
96      "mulq  %4           \n\t"                            \
97      "movq  %%rax,%0     \n\t"                            \
98      "movq  %%rdx,%1     \n\t"                            \
99      "xorq  %2,%2        \n\t"                            \
100      :"=r"(sc0), "=r"(sc1), "=r"(sc2): "g"(i), "g"(j) :"%rax","%rdx","cc");
101
102 #define SQRADDAC(i, j)                                                         \
103 __asm__ (                                                     \
104      "movq  %6,%%rax     \n\t"                            \
105      "mulq  %7           \n\t"                            \
106      "addq  %%rax,%0     \n\t"                            \
107      "adcq  %%rdx,%1     \n\t"                            \
108      "adcq  $0,%2        \n\t"                            \
109      :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","cc");
110
111 #define SQRADDDB                                                               \
112 __asm__ (                                                     \
113      "addq %6,%0         \n\t"                            \
114      "adcq %7,%1         \n\t"                            \
115      "adcq %8,%2         \n\t"                            \
116      "addq %6,%0         \n\t"                            \
117      "adcq %7,%1         \n\t"                            \
118      "adcq %8,%2         \n\t"                            \
119      :"=&r"(c0), "=&r"(c1), "=&r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "cc");
120
121
122
123
124
125 void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C)
126 {
127    mp_digit c0, c1, c2, at[8];
128
129    memcpy(at, A->dp, 4 * sizeof(mp_digit));
130    memcpy(at+4, B->dp, 4 * sizeof(mp_digit));
131    COMBA_START;
132    
133    COMBA_CLEAR;
134    /* 0 */
135    MULADD(at[0], at[4]); 
136    COMBA_STORE(C->dp[0]);
137    /* 1 */
138    COMBA_FORWARD;
139    MULADD(at[0], at[5]);       MULADD(at[1], at[4]); 
140    COMBA_STORE(C->dp[1]);
141    /* 2 */
142    COMBA_FORWARD;
143    MULADD(at[0], at[6]);       MULADD(at[1], at[5]);       MULADD(at[2], at[4]); 
144    COMBA_STORE(C->dp[2]);
145    /* 3 */
146    COMBA_FORWARD;
147    MULADD(at[0], at[7]);       MULADD(at[1], at[6]);       MULADD(at[2], at[5]);       MULADD(at[3], at[4]); 
148    COMBA_STORE(C->dp[3]);
149    /* 4 */
150    COMBA_FORWARD;
151    MULADD(at[1], at[7]);       MULADD(at[2], at[6]);       MULADD(at[3], at[5]); 
152    COMBA_STORE(C->dp[4]);
153    /* 5 */
154    COMBA_FORWARD;
155    MULADD(at[2], at[7]);       MULADD(at[3], at[6]); 
156    COMBA_STORE(C->dp[5]);
157    /* 6 */
158    COMBA_FORWARD;
159    MULADD(at[3], at[7]); 
160    COMBA_STORE(C->dp[6]);
161    COMBA_STORE2(C->dp[7]);
162    C->used = 8;
163    C->sign = A->sign ^ B->sign;
164    mp_clamp(C);
165    COMBA_FINI;
166 }
167
168 void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C)
169 {
170    mp_digit c0, c1, c2, at[16];
171
172    memcpy(at, A->dp, 8 * sizeof(mp_digit));
173    memcpy(at+8, B->dp, 8 * sizeof(mp_digit));
174    COMBA_START;
175
176    COMBA_CLEAR;
177    /* 0 */
178    MULADD(at[0], at[8]); 
179    COMBA_STORE(C->dp[0]);
180    /* 1 */
181    COMBA_FORWARD;
182    MULADD(at[0], at[9]);       MULADD(at[1], at[8]); 
183    COMBA_STORE(C->dp[1]);
184    /* 2 */
185    COMBA_FORWARD;
186    MULADD(at[0], at[10]);       MULADD(at[1], at[9]);       MULADD(at[2], at[8]); 
187    COMBA_STORE(C->dp[2]);
188    /* 3 */
189    COMBA_FORWARD;
190    MULADD(at[0], at[11]);       MULADD(at[1], at[10]);       MULADD(at[2], at[9]);       MULADD(at[3], at[8]); 
191    COMBA_STORE(C->dp[3]);
192    /* 4 */
193    COMBA_FORWARD;
194    MULADD(at[0], at[12]);       MULADD(at[1], at[11]);       MULADD(at[2], at[10]);       MULADD(at[3], at[9]);       MULADD(at[4], at[8]); 
195    COMBA_STORE(C->dp[4]);
196    /* 5 */
197    COMBA_FORWARD;
198    MULADD(at[0], at[13]);       MULADD(at[1], at[12]);       MULADD(at[2], at[11]);       MULADD(at[3], at[10]);       MULADD(at[4], at[9]);       MULADD(at[5], at[8]); 
199    COMBA_STORE(C->dp[5]);
200    /* 6 */
201    COMBA_FORWARD;
202    MULADD(at[0], at[14]);       MULADD(at[1], at[13]);       MULADD(at[2], at[12]);       MULADD(at[3], at[11]);       MULADD(at[4], at[10]);       MULADD(at[5], at[9]);       MULADD(at[6], at[8]); 
203    COMBA_STORE(C->dp[6]);
204    /* 7 */
205    COMBA_FORWARD;
206    MULADD(at[0], at[15]);       MULADD(at[1], at[14]);       MULADD(at[2], at[13]);       MULADD(at[3], at[12]);       MULADD(at[4], at[11]);       MULADD(at[5], at[10]);       MULADD(at[6], at[9]);       MULADD(at[7], at[8]); 
207    COMBA_STORE(C->dp[7]);
208    /* 8 */
209    COMBA_FORWARD;
210    MULADD(at[1], at[15]);       MULADD(at[2], at[14]);       MULADD(at[3], at[13]);       MULADD(at[4], at[12]);       MULADD(at[5], at[11]);       MULADD(at[6], at[10]);       MULADD(at[7], at[9]); 
211    COMBA_STORE(C->dp[8]);
212    /* 9 */
213    COMBA_FORWARD;
214    MULADD(at[2], at[15]);       MULADD(at[3], at[14]);       MULADD(at[4], at[13]);       MULADD(at[5], at[12]);       MULADD(at[6], at[11]);       MULADD(at[7], at[10]); 
215    COMBA_STORE(C->dp[9]);
216    /* 10 */
217    COMBA_FORWARD;
218    MULADD(at[3], at[15]);       MULADD(at[4], at[14]);       MULADD(at[5], at[13]);       MULADD(at[6], at[12]);       MULADD(at[7], at[11]); 
219    COMBA_STORE(C->dp[10]);
220    /* 11 */
221    COMBA_FORWARD;
222    MULADD(at[4], at[15]);       MULADD(at[5], at[14]);       MULADD(at[6], at[13]);       MULADD(at[7], at[12]); 
223    COMBA_STORE(C->dp[11]);
224    /* 12 */
225    COMBA_FORWARD;
226    MULADD(at[5], at[15]);       MULADD(at[6], at[14]);       MULADD(at[7], at[13]); 
227    COMBA_STORE(C->dp[12]);
228    /* 13 */
229    COMBA_FORWARD;
230    MULADD(at[6], at[15]);       MULADD(at[7], at[14]); 
231    COMBA_STORE(C->dp[13]);
232    /* 14 */
233    COMBA_FORWARD;
234    MULADD(at[7], at[15]); 
235    COMBA_STORE(C->dp[14]);
236    COMBA_STORE2(C->dp[15]);
237    C->used = 16;
238    C->sign = A->sign ^ B->sign;
239    mp_clamp(C);
240    COMBA_FINI;
241 }
242
243 void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C)
244 {
245    mp_digit c0, c1, c2, at[32];
246
247    memcpy(at, A->dp, 16 * sizeof(mp_digit));
248    memcpy(at+16, B->dp, 16 * sizeof(mp_digit));
249    COMBA_START;
250
251    COMBA_CLEAR;
252    /* 0 */
253    MULADD(at[0], at[16]); 
254    COMBA_STORE(C->dp[0]);
255    /* 1 */
256    COMBA_FORWARD;
257    MULADD(at[0], at[17]);       MULADD(at[1], at[16]); 
258    COMBA_STORE(C->dp[1]);
259    /* 2 */
260    COMBA_FORWARD;
261    MULADD(at[0], at[18]);       MULADD(at[1], at[17]);       MULADD(at[2], at[16]); 
262    COMBA_STORE(C->dp[2]);
263    /* 3 */
264    COMBA_FORWARD;
265    MULADD(at[0], at[19]);       MULADD(at[1], at[18]);       MULADD(at[2], at[17]);       MULADD(at[3], at[16]); 
266    COMBA_STORE(C->dp[3]);
267    /* 4 */
268    COMBA_FORWARD;
269    MULADD(at[0], at[20]);       MULADD(at[1], at[19]);       MULADD(at[2], at[18]);       MULADD(at[3], at[17]);       MULADD(at[4], at[16]); 
270    COMBA_STORE(C->dp[4]);
271    /* 5 */
272    COMBA_FORWARD;
273    MULADD(at[0], at[21]);       MULADD(at[1], at[20]);       MULADD(at[2], at[19]);       MULADD(at[3], at[18]);       MULADD(at[4], at[17]);       MULADD(at[5], at[16]); 
274    COMBA_STORE(C->dp[5]);
275    /* 6 */
276    COMBA_FORWARD;
277    MULADD(at[0], at[22]);       MULADD(at[1], at[21]);       MULADD(at[2], at[20]);       MULADD(at[3], at[19]);       MULADD(at[4], at[18]);       MULADD(at[5], at[17]);       MULADD(at[6], at[16]); 
278    COMBA_STORE(C->dp[6]);
279    /* 7 */
280    COMBA_FORWARD;
281    MULADD(at[0], at[23]);       MULADD(at[1], at[22]);       MULADD(at[2], at[21]);       MULADD(at[3], at[20]);       MULADD(at[4], at[19]);       MULADD(at[5], at[18]);       MULADD(at[6], at[17]);       MULADD(at[7], at[16]); 
282    COMBA_STORE(C->dp[7]);
283    /* 8 */
284    COMBA_FORWARD;
285    MULADD(at[0], at[24]);       MULADD(at[1], at[23]);       MULADD(at[2], at[22]);       MULADD(at[3], at[21]);       MULADD(at[4], at[20]);       MULADD(at[5], at[19]);       MULADD(at[6], at[18]);       MULADD(at[7], at[17]);       MULADD(at[8], at[16]); 
286    COMBA_STORE(C->dp[8]);
287    /* 9 */
288    COMBA_FORWARD;
289    MULADD(at[0], at[25]);       MULADD(at[1], at[24]);       MULADD(at[2], at[23]);       MULADD(at[3], at[22]);       MULADD(at[4], at[21]);       MULADD(at[5], at[20]);       MULADD(at[6], at[19]);       MULADD(at[7], at[18]);       MULADD(at[8], at[17]);       MULADD(at[9], at[16]); 
290    COMBA_STORE(C->dp[9]);
291    /* 10 */
292    COMBA_FORWARD;
293    MULADD(at[0], at[26]);       MULADD(at[1], at[25]);       MULADD(at[2], at[24]);       MULADD(at[3], at[23]);       MULADD(at[4], at[22]);       MULADD(at[5], at[21]);       MULADD(at[6], at[20]);       MULADD(at[7], at[19]);       MULADD(at[8], at[18]);       MULADD(at[9], at[17]);       MULADD(at[10], at[16]); 
294    COMBA_STORE(C->dp[10]);
295    /* 11 */
296    COMBA_FORWARD;
297    MULADD(at[0], at[27]);       MULADD(at[1], at[26]);       MULADD(at[2], at[25]);       MULADD(at[3], at[24]);       MULADD(at[4], at[23]);       MULADD(at[5], at[22]);       MULADD(at[6], at[21]);       MULADD(at[7], at[20]);       MULADD(at[8], at[19]);       MULADD(at[9], at[18]);       MULADD(at[10], at[17]);       MULADD(at[11], at[16]); 
298    COMBA_STORE(C->dp[11]);
299    /* 12 */
300    COMBA_FORWARD;
301    MULADD(at[0], at[28]);       MULADD(at[1], at[27]);       MULADD(at[2], at[26]);       MULADD(at[3], at[25]);       MULADD(at[4], at[24]);       MULADD(at[5], at[23]);       MULADD(at[6], at[22]);       MULADD(at[7], at[21]);       MULADD(at[8], at[20]);       MULADD(at[9], at[19]);       MULADD(at[10], at[18]);       MULADD(at[11], at[17]);       MULADD(at[12], at[16]); 
302    COMBA_STORE(C->dp[12]);
303    /* 13 */
304    COMBA_FORWARD;
305    MULADD(at[0], at[29]);       MULADD(at[1], at[28]);       MULADD(at[2], at[27]);       MULADD(at[3], at[26]);       MULADD(at[4], at[25]);       MULADD(at[5], at[24]);       MULADD(at[6], at[23]);       MULADD(at[7], at[22]);       MULADD(at[8], at[21]);       MULADD(at[9], at[20]);       MULADD(at[10], at[19]);       MULADD(at[11], at[18]);       MULADD(at[12], at[17]);       MULADD(at[13], at[16]); 
306    COMBA_STORE(C->dp[13]);
307    /* 14 */
308    COMBA_FORWARD;
309    MULADD(at[0], at[30]);       MULADD(at[1], at[29]);       MULADD(at[2], at[28]);       MULADD(at[3], at[27]);       MULADD(at[4], at[26]);       MULADD(at[5], at[25]);       MULADD(at[6], at[24]);       MULADD(at[7], at[23]);       MULADD(at[8], at[22]);       MULADD(at[9], at[21]);       MULADD(at[10], at[20]);       MULADD(at[11], at[19]);       MULADD(at[12], at[18]);       MULADD(at[13], at[17]);       MULADD(at[14], at[16]); 
310    COMBA_STORE(C->dp[14]);
311    /* 15 */
312    COMBA_FORWARD;
313    MULADD(at[0], at[31]);       MULADD(at[1], at[30]);       MULADD(at[2], at[29]);       MULADD(at[3], at[28]);       MULADD(at[4], at[27]);       MULADD(at[5], at[26]);       MULADD(at[6], at[25]);       MULADD(at[7], at[24]);       MULADD(at[8], at[23]);       MULADD(at[9], at[22]);       MULADD(at[10], at[21]);       MULADD(at[11], at[20]);       MULADD(at[12], at[19]);       MULADD(at[13], at[18]);       MULADD(at[14], at[17]);       MULADD(at[15], at[16]); 
314    COMBA_STORE(C->dp[15]);
315    /* 16 */
316    COMBA_FORWARD;
317    MULADD(at[1], at[31]);       MULADD(at[2], at[30]);       MULADD(at[3], at[29]);       MULADD(at[4], at[28]);       MULADD(at[5], at[27]);       MULADD(at[6], at[26]);       MULADD(at[7], at[25]);       MULADD(at[8], at[24]);       MULADD(at[9], at[23]);       MULADD(at[10], at[22]);       MULADD(at[11], at[21]);       MULADD(at[12], at[20]);       MULADD(at[13], at[19]);       MULADD(at[14], at[18]);       MULADD(at[15], at[17]); 
318    COMBA_STORE(C->dp[16]);
319    /* 17 */
320    COMBA_FORWARD;
321    MULADD(at[2], at[31]);       MULADD(at[3], at[30]);       MULADD(at[4], at[29]);       MULADD(at[5], at[28]);       MULADD(at[6], at[27]);       MULADD(at[7], at[26]);       MULADD(at[8], at[25]);       MULADD(at[9], at[24]);       MULADD(at[10], at[23]);       MULADD(at[11], at[22]);       MULADD(at[12], at[21]);       MULADD(at[13], at[20]);       MULADD(at[14], at[19]);       MULADD(at[15], at[18]); 
322    COMBA_STORE(C->dp[17]);
323    /* 18 */
324    COMBA_FORWARD;
325    MULADD(at[3], at[31]);       MULADD(at[4], at[30]);       MULADD(at[5], at[29]);       MULADD(at[6], at[28]);       MULADD(at[7], at[27]);       MULADD(at[8], at[26]);       MULADD(at[9], at[25]);       MULADD(at[10], at[24]);       MULADD(at[11], at[23]);       MULADD(at[12], at[22]);       MULADD(at[13], at[21]);       MULADD(at[14], at[20]);       MULADD(at[15], at[19]); 
326    COMBA_STORE(C->dp[18]);
327    /* 19 */
328    COMBA_FORWARD;
329    MULADD(at[4], at[31]);       MULADD(at[5], at[30]);       MULADD(at[6], at[29]);       MULADD(at[7], at[28]);       MULADD(at[8], at[27]);       MULADD(at[9], at[26]);       MULADD(at[10], at[25]);       MULADD(at[11], at[24]);       MULADD(at[12], at[23]);       MULADD(at[13], at[22]);       MULADD(at[14], at[21]);       MULADD(at[15], at[20]); 
330    COMBA_STORE(C->dp[19]);
331    /* 20 */
332    COMBA_FORWARD;
333    MULADD(at[5], at[31]);       MULADD(at[6], at[30]);       MULADD(at[7], at[29]);       MULADD(at[8], at[28]);       MULADD(at[9], at[27]);       MULADD(at[10], at[26]);       MULADD(at[11], at[25]);       MULADD(at[12], at[24]);       MULADD(at[13], at[23]);       MULADD(at[14], at[22]);       MULADD(at[15], at[21]); 
334    COMBA_STORE(C->dp[20]);
335    /* 21 */
336    COMBA_FORWARD;
337    MULADD(at[6], at[31]);       MULADD(at[7], at[30]);       MULADD(at[8], at[29]);       MULADD(at[9], at[28]);       MULADD(at[10], at[27]);       MULADD(at[11], at[26]);       MULADD(at[12], at[25]);       MULADD(at[13], at[24]);       MULADD(at[14], at[23]);       MULADD(at[15], at[22]); 
338    COMBA_STORE(C->dp[21]);
339    /* 22 */
340    COMBA_FORWARD;
341    MULADD(at[7], at[31]);       MULADD(at[8], at[30]);       MULADD(at[9], at[29]);       MULADD(at[10], at[28]);       MULADD(at[11], at[27]);       MULADD(at[12], at[26]);       MULADD(at[13], at[25]);       MULADD(at[14], at[24]);       MULADD(at[15], at[23]); 
342    COMBA_STORE(C->dp[22]);
343    /* 23 */
344    COMBA_FORWARD;
345    MULADD(at[8], at[31]);       MULADD(at[9], at[30]);       MULADD(at[10], at[29]);       MULADD(at[11], at[28]);       MULADD(at[12], at[27]);       MULADD(at[13], at[26]);       MULADD(at[14], at[25]);       MULADD(at[15], at[24]); 
346    COMBA_STORE(C->dp[23]);
347    /* 24 */
348    COMBA_FORWARD;
349    MULADD(at[9], at[31]);       MULADD(at[10], at[30]);       MULADD(at[11], at[29]);       MULADD(at[12], at[28]);       MULADD(at[13], at[27]);       MULADD(at[14], at[26]);       MULADD(at[15], at[25]); 
350    COMBA_STORE(C->dp[24]);
351    /* 25 */
352    COMBA_FORWARD;
353    MULADD(at[10], at[31]);       MULADD(at[11], at[30]);       MULADD(at[12], at[29]);       MULADD(at[13], at[28]);       MULADD(at[14], at[27]);       MULADD(at[15], at[26]); 
354    COMBA_STORE(C->dp[25]);
355    /* 26 */
356    COMBA_FORWARD;
357    MULADD(at[11], at[31]);       MULADD(at[12], at[30]);       MULADD(at[13], at[29]);       MULADD(at[14], at[28]);       MULADD(at[15], at[27]); 
358    COMBA_STORE(C->dp[26]);
359    /* 27 */
360    COMBA_FORWARD;
361    MULADD(at[12], at[31]);       MULADD(at[13], at[30]);       MULADD(at[14], at[29]);       MULADD(at[15], at[28]); 
362    COMBA_STORE(C->dp[27]);
363    /* 28 */
364    COMBA_FORWARD;
365    MULADD(at[13], at[31]);       MULADD(at[14], at[30]);       MULADD(at[15], at[29]); 
366    COMBA_STORE(C->dp[28]);
367    /* 29 */
368    COMBA_FORWARD;
369    MULADD(at[14], at[31]);       MULADD(at[15], at[30]); 
370    COMBA_STORE(C->dp[29]);
371    /* 30 */
372    COMBA_FORWARD;
373    MULADD(at[15], at[31]); 
374    COMBA_STORE(C->dp[30]);
375    COMBA_STORE2(C->dp[31]);
376    C->used = 32;
377    C->sign = A->sign ^ B->sign;
378    mp_clamp(C);
379    COMBA_FINI;
380 }
381
382 void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C)
383 {
384    mp_digit c0, c1, c2, at[64];
385
386    memcpy(at, A->dp, 32 * sizeof(mp_digit));
387    memcpy(at+32, B->dp, 32 * sizeof(mp_digit));
388    COMBA_START;
389
390    COMBA_CLEAR;
391    /* 0 */
392    MULADD(at[0], at[32]); 
393    COMBA_STORE(C->dp[0]);
394    /* 1 */
395    COMBA_FORWARD;
396    MULADD(at[0], at[33]);    MULADD(at[1], at[32]); 
397    COMBA_STORE(C->dp[1]);
398    /* 2 */
399    COMBA_FORWARD;
400    MULADD(at[0], at[34]);    MULADD(at[1], at[33]);    MULADD(at[2], at[32]); 
401    COMBA_STORE(C->dp[2]);
402    /* 3 */
403    COMBA_FORWARD;
404    MULADD(at[0], at[35]);    MULADD(at[1], at[34]);    MULADD(at[2], at[33]);    MULADD(at[3], at[32]); 
405    COMBA_STORE(C->dp[3]);
406    /* 4 */
407    COMBA_FORWARD;
408    MULADD(at[0], at[36]);    MULADD(at[1], at[35]);    MULADD(at[2], at[34]);    MULADD(at[3], at[33]);    MULADD(at[4], at[32]); 
409    COMBA_STORE(C->dp[4]);
410    /* 5 */
411    COMBA_FORWARD;
412    MULADD(at[0], at[37]);    MULADD(at[1], at[36]);    MULADD(at[2], at[35]);    MULADD(at[3], at[34]);    MULADD(at[4], at[33]);    MULADD(at[5], at[32]); 
413    COMBA_STORE(C->dp[5]);
414    /* 6 */
415    COMBA_FORWARD;
416    MULADD(at[0], at[38]);    MULADD(at[1], at[37]);    MULADD(at[2], at[36]);    MULADD(at[3], at[35]);    MULADD(at[4], at[34]);    MULADD(at[5], at[33]);    MULADD(at[6], at[32]); 
417    COMBA_STORE(C->dp[6]);
418    /* 7 */
419    COMBA_FORWARD;
420    MULADD(at[0], at[39]);    MULADD(at[1], at[38]);    MULADD(at[2], at[37]);    MULADD(at[3], at[36]);    MULADD(at[4], at[35]);    MULADD(at[5], at[34]);    MULADD(at[6], at[33]);    MULADD(at[7], at[32]); 
421    COMBA_STORE(C->dp[7]);
422    /* 8 */
423    COMBA_FORWARD;
424    MULADD(at[0], at[40]);    MULADD(at[1], at[39]);    MULADD(at[2], at[38]);    MULADD(at[3], at[37]);    MULADD(at[4], at[36]);    MULADD(at[5], at[35]);    MULADD(at[6], at[34]);    MULADD(at[7], at[33]);    MULADD(at[8], at[32]); 
425    COMBA_STORE(C->dp[8]);
426    /* 9 */
427    COMBA_FORWARD;
428    MULADD(at[0], at[41]);    MULADD(at[1], at[40]);    MULADD(at[2], at[39]);    MULADD(at[3], at[38]);    MULADD(at[4], at[37]);    MULADD(at[5], at[36]);    MULADD(at[6], at[35]);    MULADD(at[7], at[34]);    MULADD(at[8], at[33]);    MULADD(at[9], at[32]); 
429    COMBA_STORE(C->dp[9]);
430    /* 10 */
431    COMBA_FORWARD;
432    MULADD(at[0], at[42]);    MULADD(at[1], at[41]);    MULADD(at[2], at[40]);    MULADD(at[3], at[39]);    MULADD(at[4], at[38]);    MULADD(at[5], at[37]);    MULADD(at[6], at[36]);    MULADD(at[7], at[35]);    MULADD(at[8], at[34]);    MULADD(at[9], at[33]);    MULADD(at[10], at[32]); 
433    COMBA_STORE(C->dp[10]);
434    /* 11 */
435    COMBA_FORWARD;
436    MULADD(at[0], at[43]);    MULADD(at[1], at[42]);    MULADD(at[2], at[41]);    MULADD(at[3], at[40]);    MULADD(at[4], at[39]);    MULADD(at[5], at[38]);    MULADD(at[6], at[37]);    MULADD(at[7], at[36]);    MULADD(at[8], at[35]);    MULADD(at[9], at[34]);    MULADD(at[10], at[33]);    MULADD(at[11], at[32]); 
437    COMBA_STORE(C->dp[11]);
438    /* 12 */
439    COMBA_FORWARD;
440    MULADD(at[0], at[44]);    MULADD(at[1], at[43]);    MULADD(at[2], at[42]);    MULADD(at[3], at[41]);    MULADD(at[4], at[40]);    MULADD(at[5], at[39]);    MULADD(at[6], at[38]);    MULADD(at[7], at[37]);    MULADD(at[8], at[36]);    MULADD(at[9], at[35]);    MULADD(at[10], at[34]);    MULADD(at[11], at[33]);    MULADD(at[12], at[32]); 
441    COMBA_STORE(C->dp[12]);
442    /* 13 */
443    COMBA_FORWARD;
444    MULADD(at[0], at[45]);    MULADD(at[1], at[44]);    MULADD(at[2], at[43]);    MULADD(at[3], at[42]);    MULADD(at[4], at[41]);    MULADD(at[5], at[40]);    MULADD(at[6], at[39]);    MULADD(at[7], at[38]);    MULADD(at[8], at[37]);    MULADD(at[9], at[36]);    MULADD(at[10], at[35]);    MULADD(at[11], at[34]);    MULADD(at[12], at[33]);    MULADD(at[13], at[32]); 
445    COMBA_STORE(C->dp[13]);
446    /* 14 */
447    COMBA_FORWARD;
448    MULADD(at[0], at[46]);    MULADD(at[1], at[45]);    MULADD(at[2], at[44]);    MULADD(at[3], at[43]);    MULADD(at[4], at[42]);    MULADD(at[5], at[41]);    MULADD(at[6], at[40]);    MULADD(at[7], at[39]);    MULADD(at[8], at[38]);    MULADD(at[9], at[37]);    MULADD(at[10], at[36]);    MULADD(at[11], at[35]);    MULADD(at[12], at[34]);    MULADD(at[13], at[33]);    MULADD(at[14], at[32]); 
449    COMBA_STORE(C->dp[14]);
450    /* 15 */
451    COMBA_FORWARD;
452    MULADD(at[0], at[47]);    MULADD(at[1], at[46]);    MULADD(at[2], at[45]);    MULADD(at[3], at[44]);    MULADD(at[4], at[43]);    MULADD(at[5], at[42]);    MULADD(at[6], at[41]);    MULADD(at[7], at[40]);    MULADD(at[8], at[39]);    MULADD(at[9], at[38]);    MULADD(at[10], at[37]);    MULADD(at[11], at[36]);    MULADD(at[12], at[35]);    MULADD(at[13], at[34]);    MULADD(at[14], at[33]);    MULADD(at[15], at[32]); 
453    COMBA_STORE(C->dp[15]);
454    /* 16 */
455    COMBA_FORWARD;
456    MULADD(at[0], at[48]);    MULADD(at[1], at[47]);    MULADD(at[2], at[46]);    MULADD(at[3], at[45]);    MULADD(at[4], at[44]);    MULADD(at[5], at[43]);    MULADD(at[6], at[42]);    MULADD(at[7], at[41]);    MULADD(at[8], at[40]);    MULADD(at[9], at[39]);    MULADD(at[10], at[38]);    MULADD(at[11], at[37]);    MULADD(at[12], at[36]);    MULADD(at[13], at[35]);    MULADD(at[14], at[34]);    MULADD(at[15], at[33]);    MULADD(at[16], at[32]); 
457    COMBA_STORE(C->dp[16]);
458    /* 17 */
459    COMBA_FORWARD;
460    MULADD(at[0], at[49]);    MULADD(at[1], at[48]);    MULADD(at[2], at[47]);    MULADD(at[3], at[46]);    MULADD(at[4], at[45]);    MULADD(at[5], at[44]);    MULADD(at[6], at[43]);    MULADD(at[7], at[42]);    MULADD(at[8], at[41]);    MULADD(at[9], at[40]);    MULADD(at[10], at[39]);    MULADD(at[11], at[38]);    MULADD(at[12], at[37]);    MULADD(at[13], at[36]);    MULADD(at[14], at[35]);    MULADD(at[15], at[34]);    MULADD(at[16], at[33]);    MULADD(at[17], at[32]); 
461    COMBA_STORE(C->dp[17]);
462    /* 18 */
463    COMBA_FORWARD;
464    MULADD(at[0], at[50]);    MULADD(at[1], at[49]);    MULADD(at[2], at[48]);    MULADD(at[3], at[47]);    MULADD(at[4], at[46]);    MULADD(at[5], at[45]);    MULADD(at[6], at[44]);    MULADD(at[7], at[43]);    MULADD(at[8], at[42]);    MULADD(at[9], at[41]);    MULADD(at[10], at[40]);    MULADD(at[11], at[39]);    MULADD(at[12], at[38]);    MULADD(at[13], at[37]);    MULADD(at[14], at[36]);    MULADD(at[15], at[35]);    MULADD(at[16], at[34]);    MULADD(at[17], at[33]);    MULADD(at[18], at[32]); 
465    COMBA_STORE(C->dp[18]);
466    /* 19 */
467    COMBA_FORWARD;
468    MULADD(at[0], at[51]);    MULADD(at[1], at[50]);    MULADD(at[2], at[49]);    MULADD(at[3], at[48]);    MULADD(at[4], at[47]);    MULADD(at[5], at[46]);    MULADD(at[6], at[45]);    MULADD(at[7], at[44]);    MULADD(at[8], at[43]);    MULADD(at[9], at[42]);    MULADD(at[10], at[41]);    MULADD(at[11], at[40]);    MULADD(at[12], at[39]);    MULADD(at[13], at[38]);    MULADD(at[14], at[37]);    MULADD(at[15], at[36]);    MULADD(at[16], at[35]);    MULADD(at[17], at[34]);    MULADD(at[18], at[33]);    MULADD(at[19], at[32]); 
469    COMBA_STORE(C->dp[19]);
470    /* 20 */
471    COMBA_FORWARD;
472    MULADD(at[0], at[52]);    MULADD(at[1], at[51]);    MULADD(at[2], at[50]);    MULADD(at[3], at[49]);    MULADD(at[4], at[48]);    MULADD(at[5], at[47]);    MULADD(at[6], at[46]);    MULADD(at[7], at[45]);    MULADD(at[8], at[44]);    MULADD(at[9], at[43]);    MULADD(at[10], at[42]);    MULADD(at[11], at[41]);    MULADD(at[12], at[40]);    MULADD(at[13], at[39]);    MULADD(at[14], at[38]);    MULADD(at[15], at[37]);    MULADD(at[16], at[36]);    MULADD(at[17], at[35]);    MULADD(at[18], at[34]);    MULADD(at[19], at[33]);    MULADD(at[20], at[32]); 
473    COMBA_STORE(C->dp[20]);
474    /* 21 */
475    COMBA_FORWARD;
476    MULADD(at[0], at[53]);    MULADD(at[1], at[52]);    MULADD(at[2], at[51]);    MULADD(at[3], at[50]);    MULADD(at[4], at[49]);    MULADD(at[5], at[48]);    MULADD(at[6], at[47]);    MULADD(at[7], at[46]);    MULADD(at[8], at[45]);    MULADD(at[9], at[44]);    MULADD(at[10], at[43]);    MULADD(at[11], at[42]);    MULADD(at[12], at[41]);    MULADD(at[13], at[40]);    MULADD(at[14], at[39]);    MULADD(at[15], at[38]);    MULADD(at[16], at[37]);    MULADD(at[17], at[36]);    MULADD(at[18], at[35]);    MULADD(at[19], at[34]);    MULADD(at[20], at[33]);    MULADD(at[21], at[32]); 
477    COMBA_STORE(C->dp[21]);
478    /* 22 */
479    COMBA_FORWARD;
480    MULADD(at[0], at[54]);    MULADD(at[1], at[53]);    MULADD(at[2], at[52]);    MULADD(at[3], at[51]);    MULADD(at[4], at[50]);    MULADD(at[5], at[49]);    MULADD(at[6], at[48]);    MULADD(at[7], at[47]);    MULADD(at[8], at[46]);    MULADD(at[9], at[45]);    MULADD(at[10], at[44]);    MULADD(at[11], at[43]);    MULADD(at[12], at[42]);    MULADD(at[13], at[41]);    MULADD(at[14], at[40]);    MULADD(at[15], at[39]);    MULADD(at[16], at[38]);    MULADD(at[17], at[37]);    MULADD(at[18], at[36]);    MULADD(at[19], at[35]);    MULADD(at[20], at[34]);    MULADD(at[21], at[33]);    MULADD(at[22], at[32]); 
481    COMBA_STORE(C->dp[22]);
482    /* 23 */
483    COMBA_FORWARD;
484    MULADD(at[0], at[55]);    MULADD(at[1], at[54]);    MULADD(at[2], at[53]);    MULADD(at[3], at[52]);    MULADD(at[4], at[51]);    MULADD(at[5], at[50]);    MULADD(at[6], at[49]);    MULADD(at[7], at[48]);    MULADD(at[8], at[47]);    MULADD(at[9], at[46]);    MULADD(at[10], at[45]);    MULADD(at[11], at[44]);    MULADD(at[12], at[43]);    MULADD(at[13], at[42]);    MULADD(at[14], at[41]);    MULADD(at[15], at[40]);    MULADD(at[16], at[39]);    MULADD(at[17], at[38]);    MULADD(at[18], at[37]);    MULADD(at[19], at[36]);    MULADD(at[20], at[35]);    MULADD(at[21], at[34]);    MULADD(at[22], at[33]);    MULADD(at[23], at[32]); 
485    COMBA_STORE(C->dp[23]);
486    /* 24 */
487    COMBA_FORWARD;
488    MULADD(at[0], at[56]);    MULADD(at[1], at[55]);    MULADD(at[2], at[54]);    MULADD(at[3], at[53]);    MULADD(at[4], at[52]);    MULADD(at[5], at[51]);    MULADD(at[6], at[50]);    MULADD(at[7], at[49]);    MULADD(at[8], at[48]);    MULADD(at[9], at[47]);    MULADD(at[10], at[46]);    MULADD(at[11], at[45]);    MULADD(at[12], at[44]);    MULADD(at[13], at[43]);    MULADD(at[14], at[42]);    MULADD(at[15], at[41]);    MULADD(at[16], at[40]);    MULADD(at[17], at[39]);    MULADD(at[18], at[38]);    MULADD(at[19], at[37]);    MULADD(at[20], at[36]);    MULADD(at[21], at[35]);    MULADD(at[22], at[34]);    MULADD(at[23], at[33]);    MULADD(at[24], at[32]); 
489    COMBA_STORE(C->dp[24]);
490    /* 25 */
491    COMBA_FORWARD;
492    MULADD(at[0], at[57]);    MULADD(at[1], at[56]);    MULADD(at[2], at[55]);    MULADD(at[3], at[54]);    MULADD(at[4], at[53]);    MULADD(at[5], at[52]);    MULADD(at[6], at[51]);    MULADD(at[7], at[50]);    MULADD(at[8], at[49]);    MULADD(at[9], at[48]);    MULADD(at[10], at[47]);    MULADD(at[11], at[46]);    MULADD(at[12], at[45]);    MULADD(at[13], at[44]);    MULADD(at[14], at[43]);    MULADD(at[15], at[42]);    MULADD(at[16], at[41]);    MULADD(at[17], at[40]);    MULADD(at[18], at[39]);    MULADD(at[19], at[38]);    MULADD(at[20], at[37]);    MULADD(at[21], at[36]);    MULADD(at[22], at[35]);    MULADD(at[23], at[34]);    MULADD(at[24], at[33]);    MULADD(at[25], at[32]); 
493    COMBA_STORE(C->dp[25]);
494    /* 26 */
495    COMBA_FORWARD;
496    MULADD(at[0], at[58]);    MULADD(at[1], at[57]);    MULADD(at[2], at[56]);    MULADD(at[3], at[55]);    MULADD(at[4], at[54]);    MULADD(at[5], at[53]);    MULADD(at[6], at[52]);    MULADD(at[7], at[51]);    MULADD(at[8], at[50]);    MULADD(at[9], at[49]);    MULADD(at[10], at[48]);    MULADD(at[11], at[47]);    MULADD(at[12], at[46]);    MULADD(at[13], at[45]);    MULADD(at[14], at[44]);    MULADD(at[15], at[43]);    MULADD(at[16], at[42]);    MULADD(at[17], at[41]);    MULADD(at[18], at[40]);    MULADD(at[19], at[39]);    MULADD(at[20], at[38]);    MULADD(at[21], at[37]);    MULADD(at[22], at[36]);    MULADD(at[23], at[35]);    MULADD(at[24], at[34]);    MULADD(at[25], at[33]);    MULADD(at[26], at[32]); 
497    COMBA_STORE(C->dp[26]);
498    /* 27 */
499    COMBA_FORWARD;
500    MULADD(at[0], at[59]);    MULADD(at[1], at[58]);    MULADD(at[2], at[57]);    MULADD(at[3], at[56]);    MULADD(at[4], at[55]);    MULADD(at[5], at[54]);    MULADD(at[6], at[53]);    MULADD(at[7], at[52]);    MULADD(at[8], at[51]);    MULADD(at[9], at[50]);    MULADD(at[10], at[49]);    MULADD(at[11], at[48]);    MULADD(at[12], at[47]);    MULADD(at[13], at[46]);    MULADD(at[14], at[45]);    MULADD(at[15], at[44]);    MULADD(at[16], at[43]);    MULADD(at[17], at[42]);    MULADD(at[18], at[41]);    MULADD(at[19], at[40]);    MULADD(at[20], at[39]);    MULADD(at[21], at[38]);    MULADD(at[22], at[37]);    MULADD(at[23], at[36]);    MULADD(at[24], at[35]);    MULADD(at[25], at[34]);    MULADD(at[26], at[33]);    MULADD(at[27], at[32]); 
501    COMBA_STORE(C->dp[27]);
502    /* 28 */
503    COMBA_FORWARD;
504    MULADD(at[0], at[60]);    MULADD(at[1], at[59]);    MULADD(at[2], at[58]);    MULADD(at[3], at[57]);    MULADD(at[4], at[56]);    MULADD(at[5], at[55]);    MULADD(at[6], at[54]);    MULADD(at[7], at[53]);    MULADD(at[8], at[52]);    MULADD(at[9], at[51]);    MULADD(at[10], at[50]);    MULADD(at[11], at[49]);    MULADD(at[12], at[48]);    MULADD(at[13], at[47]);    MULADD(at[14], at[46]);    MULADD(at[15], at[45]);    MULADD(at[16], at[44]);    MULADD(at[17], at[43]);    MULADD(at[18], at[42]);    MULADD(at[19], at[41]);    MULADD(at[20], at[40]);    MULADD(at[21], at[39]);    MULADD(at[22], at[38]);    MULADD(at[23], at[37]);    MULADD(at[24], at[36]);    MULADD(at[25], at[35]);    MULADD(at[26], at[34]);    MULADD(at[27], at[33]);    MULADD(at[28], at[32]); 
505    COMBA_STORE(C->dp[28]);
506    /* 29 */
507    COMBA_FORWARD;
508    MULADD(at[0], at[61]);    MULADD(at[1], at[60]);    MULADD(at[2], at[59]);    MULADD(at[3], at[58]);    MULADD(at[4], at[57]);    MULADD(at[5], at[56]);    MULADD(at[6], at[55]);    MULADD(at[7], at[54]);    MULADD(at[8], at[53]);    MULADD(at[9], at[52]);    MULADD(at[10], at[51]);    MULADD(at[11], at[50]);    MULADD(at[12], at[49]);    MULADD(at[13], at[48]);    MULADD(at[14], at[47]);    MULADD(at[15], at[46]);    MULADD(at[16], at[45]);    MULADD(at[17], at[44]);    MULADD(at[18], at[43]);    MULADD(at[19], at[42]);    MULADD(at[20], at[41]);    MULADD(at[21], at[40]);    MULADD(at[22], at[39]);    MULADD(at[23], at[38]);    MULADD(at[24], at[37]);    MULADD(at[25], at[36]);    MULADD(at[26], at[35]);    MULADD(at[27], at[34]);    MULADD(at[28], at[33]);    MULADD(at[29], at[32]); 
509    COMBA_STORE(C->dp[29]);
510    /* 30 */
511    COMBA_FORWARD;
512    MULADD(at[0], at[62]);    MULADD(at[1], at[61]);    MULADD(at[2], at[60]);    MULADD(at[3], at[59]);    MULADD(at[4], at[58]);    MULADD(at[5], at[57]);    MULADD(at[6], at[56]);    MULADD(at[7], at[55]);    MULADD(at[8], at[54]);    MULADD(at[9], at[53]);    MULADD(at[10], at[52]);    MULADD(at[11], at[51]);    MULADD(at[12], at[50]);    MULADD(at[13], at[49]);    MULADD(at[14], at[48]);    MULADD(at[15], at[47]);    MULADD(at[16], at[46]);    MULADD(at[17], at[45]);    MULADD(at[18], at[44]);    MULADD(at[19], at[43]);    MULADD(at[20], at[42]);    MULADD(at[21], at[41]);    MULADD(at[22], at[40]);    MULADD(at[23], at[39]);    MULADD(at[24], at[38]);    MULADD(at[25], at[37]);    MULADD(at[26], at[36]);    MULADD(at[27], at[35]);    MULADD(at[28], at[34]);    MULADD(at[29], at[33]);    MULADD(at[30], at[32]); 
513    COMBA_STORE(C->dp[30]);
514    /* 31 */
515    COMBA_FORWARD;
516    MULADD(at[0], at[63]);    MULADD(at[1], at[62]);    MULADD(at[2], at[61]);    MULADD(at[3], at[60]);    MULADD(at[4], at[59]);    MULADD(at[5], at[58]);    MULADD(at[6], at[57]);    MULADD(at[7], at[56]);    MULADD(at[8], at[55]);    MULADD(at[9], at[54]);    MULADD(at[10], at[53]);    MULADD(at[11], at[52]);    MULADD(at[12], at[51]);    MULADD(at[13], at[50]);    MULADD(at[14], at[49]);    MULADD(at[15], at[48]);    MULADD(at[16], at[47]);    MULADD(at[17], at[46]);    MULADD(at[18], at[45]);    MULADD(at[19], at[44]);    MULADD(at[20], at[43]);    MULADD(at[21], at[42]);    MULADD(at[22], at[41]);    MULADD(at[23], at[40]);    MULADD(at[24], at[39]);    MULADD(at[25], at[38]);    MULADD(at[26], at[37]);    MULADD(at[27], at[36]);    MULADD(at[28], at[35]);    MULADD(at[29], at[34]);    MULADD(at[30], at[33]);    MULADD(at[31], at[32]); 
517    COMBA_STORE(C->dp[31]);
518    /* 32 */
519    COMBA_FORWARD;
520    MULADD(at[1], at[63]);    MULADD(at[2], at[62]);    MULADD(at[3], at[61]);    MULADD(at[4], at[60]);    MULADD(at[5], at[59]);    MULADD(at[6], at[58]);    MULADD(at[7], at[57]);    MULADD(at[8], at[56]);    MULADD(at[9], at[55]);    MULADD(at[10], at[54]);    MULADD(at[11], at[53]);    MULADD(at[12], at[52]);    MULADD(at[13], at[51]);    MULADD(at[14], at[50]);    MULADD(at[15], at[49]);    MULADD(at[16], at[48]);    MULADD(at[17], at[47]);    MULADD(at[18], at[46]);    MULADD(at[19], at[45]);    MULADD(at[20], at[44]);    MULADD(at[21], at[43]);    MULADD(at[22], at[42]);    MULADD(at[23], at[41]);    MULADD(at[24], at[40]);    MULADD(at[25], at[39]);    MULADD(at[26], at[38]);    MULADD(at[27], at[37]);    MULADD(at[28], at[36]);    MULADD(at[29], at[35]);    MULADD(at[30], at[34]);    MULADD(at[31], at[33]); 
521    COMBA_STORE(C->dp[32]);
522    /* 33 */
523    COMBA_FORWARD;
524    MULADD(at[2], at[63]);    MULADD(at[3], at[62]);    MULADD(at[4], at[61]);    MULADD(at[5], at[60]);    MULADD(at[6], at[59]);    MULADD(at[7], at[58]);    MULADD(at[8], at[57]);    MULADD(at[9], at[56]);    MULADD(at[10], at[55]);    MULADD(at[11], at[54]);    MULADD(at[12], at[53]);    MULADD(at[13], at[52]);    MULADD(at[14], at[51]);    MULADD(at[15], at[50]);    MULADD(at[16], at[49]);    MULADD(at[17], at[48]);    MULADD(at[18], at[47]);    MULADD(at[19], at[46]);    MULADD(at[20], at[45]);    MULADD(at[21], at[44]);    MULADD(at[22], at[43]);    MULADD(at[23], at[42]);    MULADD(at[24], at[41]);    MULADD(at[25], at[40]);    MULADD(at[26], at[39]);    MULADD(at[27], at[38]);    MULADD(at[28], at[37]);    MULADD(at[29], at[36]);    MULADD(at[30], at[35]);    MULADD(at[31], at[34]); 
525    COMBA_STORE(C->dp[33]);
526    /* 34 */
527    COMBA_FORWARD;
528    MULADD(at[3], at[63]);    MULADD(at[4], at[62]);    MULADD(at[5], at[61]);    MULADD(at[6], at[60]);    MULADD(at[7], at[59]);    MULADD(at[8], at[58]);    MULADD(at[9], at[57]);    MULADD(at[10], at[56]);    MULADD(at[11], at[55]);    MULADD(at[12], at[54]);    MULADD(at[13], at[53]);    MULADD(at[14], at[52]);    MULADD(at[15], at[51]);    MULADD(at[16], at[50]);    MULADD(at[17], at[49]);    MULADD(at[18], at[48]);    MULADD(at[19], at[47]);    MULADD(at[20], at[46]);    MULADD(at[21], at[45]);    MULADD(at[22], at[44]);    MULADD(at[23], at[43]);    MULADD(at[24], at[42]);    MULADD(at[25], at[41]);    MULADD(at[26], at[40]);    MULADD(at[27], at[39]);    MULADD(at[28], at[38]);    MULADD(at[29], at[37]);    MULADD(at[30], at[36]);    MULADD(at[31], at[35]); 
529    COMBA_STORE(C->dp[34]);
530    /* 35 */
531    COMBA_FORWARD;
532    MULADD(at[4], at[63]);    MULADD(at[5], at[62]);    MULADD(at[6], at[61]);    MULADD(at[7], at[60]);    MULADD(at[8], at[59]);    MULADD(at[9], at[58]);    MULADD(at[10], at[57]);    MULADD(at[11], at[56]);    MULADD(at[12], at[55]);    MULADD(at[13], at[54]);    MULADD(at[14], at[53]);    MULADD(at[15], at[52]);    MULADD(at[16], at[51]);    MULADD(at[17], at[50]);    MULADD(at[18], at[49]);    MULADD(at[19], at[48]);    MULADD(at[20], at[47]);    MULADD(at[21], at[46]);    MULADD(at[22], at[45]);    MULADD(at[23], at[44]);    MULADD(at[24], at[43]);    MULADD(at[25], at[42]);    MULADD(at[26], at[41]);    MULADD(at[27], at[40]);    MULADD(at[28], at[39]);    MULADD(at[29], at[38]);    MULADD(at[30], at[37]);    MULADD(at[31], at[36]); 
533    COMBA_STORE(C->dp[35]);
534    /* 36 */
535    COMBA_FORWARD;
536    MULADD(at[5], at[63]);    MULADD(at[6], at[62]);    MULADD(at[7], at[61]);    MULADD(at[8], at[60]);    MULADD(at[9], at[59]);    MULADD(at[10], at[58]);    MULADD(at[11], at[57]);    MULADD(at[12], at[56]);    MULADD(at[13], at[55]);    MULADD(at[14], at[54]);    MULADD(at[15], at[53]);    MULADD(at[16], at[52]);    MULADD(at[17], at[51]);    MULADD(at[18], at[50]);    MULADD(at[19], at[49]);    MULADD(at[20], at[48]);    MULADD(at[21], at[47]);    MULADD(at[22], at[46]);    MULADD(at[23], at[45]);    MULADD(at[24], at[44]);    MULADD(at[25], at[43]);    MULADD(at[26], at[42]);    MULADD(at[27], at[41]);    MULADD(at[28], at[40]);    MULADD(at[29], at[39]);    MULADD(at[30], at[38]);    MULADD(at[31], at[37]); 
537    COMBA_STORE(C->dp[36]);
538    /* 37 */
539    COMBA_FORWARD;
540    MULADD(at[6], at[63]);    MULADD(at[7], at[62]);    MULADD(at[8], at[61]);    MULADD(at[9], at[60]);    MULADD(at[10], at[59]);    MULADD(at[11], at[58]);    MULADD(at[12], at[57]);    MULADD(at[13], at[56]);    MULADD(at[14], at[55]);    MULADD(at[15], at[54]);    MULADD(at[16], at[53]);    MULADD(at[17], at[52]);    MULADD(at[18], at[51]);    MULADD(at[19], at[50]);    MULADD(at[20], at[49]);    MULADD(at[21], at[48]);    MULADD(at[22], at[47]);    MULADD(at[23], at[46]);    MULADD(at[24], at[45]);    MULADD(at[25], at[44]);    MULADD(at[26], at[43]);    MULADD(at[27], at[42]);    MULADD(at[28], at[41]);    MULADD(at[29], at[40]);    MULADD(at[30], at[39]);    MULADD(at[31], at[38]); 
541    COMBA_STORE(C->dp[37]);
542    /* 38 */
543    COMBA_FORWARD;
544    MULADD(at[7], at[63]);    MULADD(at[8], at[62]);    MULADD(at[9], at[61]);    MULADD(at[10], at[60]);    MULADD(at[11], at[59]);    MULADD(at[12], at[58]);    MULADD(at[13], at[57]);    MULADD(at[14], at[56]);    MULADD(at[15], at[55]);    MULADD(at[16], at[54]);    MULADD(at[17], at[53]);    MULADD(at[18], at[52]);    MULADD(at[19], at[51]);    MULADD(at[20], at[50]);    MULADD(at[21], at[49]);    MULADD(at[22], at[48]);    MULADD(at[23], at[47]);    MULADD(at[24], at[46]);    MULADD(at[25], at[45]);    MULADD(at[26], at[44]);    MULADD(at[27], at[43]);    MULADD(at[28], at[42]);    MULADD(at[29], at[41]);    MULADD(at[30], at[40]);    MULADD(at[31], at[39]); 
545    COMBA_STORE(C->dp[38]);
546    /* 39 */
547    COMBA_FORWARD;
548    MULADD(at[8], at[63]);    MULADD(at[9], at[62]);    MULADD(at[10], at[61]);    MULADD(at[11], at[60]);    MULADD(at[12], at[59]);    MULADD(at[13], at[58]);    MULADD(at[14], at[57]);    MULADD(at[15], at[56]);    MULADD(at[16], at[55]);    MULADD(at[17], at[54]);    MULADD(at[18], at[53]);    MULADD(at[19], at[52]);    MULADD(at[20], at[51]);    MULADD(at[21], at[50]);    MULADD(at[22], at[49]);    MULADD(at[23], at[48]);    MULADD(at[24], at[47]);    MULADD(at[25], at[46]);    MULADD(at[26], at[45]);    MULADD(at[27], at[44]);    MULADD(at[28], at[43]);    MULADD(at[29], at[42]);    MULADD(at[30], at[41]);    MULADD(at[31], at[40]); 
549    COMBA_STORE(C->dp[39]);
550    /* 40 */
551    COMBA_FORWARD;
552    MULADD(at[9], at[63]);    MULADD(at[10], at[62]);    MULADD(at[11], at[61]);    MULADD(at[12], at[60]);    MULADD(at[13], at[59]);    MULADD(at[14], at[58]);    MULADD(at[15], at[57]);    MULADD(at[16], at[56]);    MULADD(at[17], at[55]);    MULADD(at[18], at[54]);    MULADD(at[19], at[53]);    MULADD(at[20], at[52]);    MULADD(at[21], at[51]);    MULADD(at[22], at[50]);    MULADD(at[23], at[49]);    MULADD(at[24], at[48]);    MULADD(at[25], at[47]);    MULADD(at[26], at[46]);    MULADD(at[27], at[45]);    MULADD(at[28], at[44]);    MULADD(at[29], at[43]);    MULADD(at[30], at[42]);    MULADD(at[31], at[41]); 
553    COMBA_STORE(C->dp[40]);
554    /* 41 */
555    COMBA_FORWARD;
556    MULADD(at[10], at[63]);    MULADD(at[11], at[62]);    MULADD(at[12], at[61]);    MULADD(at[13], at[60]);    MULADD(at[14], at[59]);    MULADD(at[15], at[58]);    MULADD(at[16], at[57]);    MULADD(at[17], at[56]);    MULADD(at[18], at[55]);    MULADD(at[19], at[54]);    MULADD(at[20], at[53]);    MULADD(at[21], at[52]);    MULADD(at[22], at[51]);    MULADD(at[23], at[50]);    MULADD(at[24], at[49]);    MULADD(at[25], at[48]);    MULADD(at[26], at[47]);    MULADD(at[27], at[46]);    MULADD(at[28], at[45]);    MULADD(at[29], at[44]);    MULADD(at[30], at[43]);    MULADD(at[31], at[42]); 
557    COMBA_STORE(C->dp[41]);
558    /* 42 */
559    COMBA_FORWARD;
560    MULADD(at[11], at[63]);    MULADD(at[12], at[62]);    MULADD(at[13], at[61]);    MULADD(at[14], at[60]);    MULADD(at[15], at[59]);    MULADD(at[16], at[58]);    MULADD(at[17], at[57]);    MULADD(at[18], at[56]);    MULADD(at[19], at[55]);    MULADD(at[20], at[54]);    MULADD(at[21], at[53]);    MULADD(at[22], at[52]);    MULADD(at[23], at[51]);    MULADD(at[24], at[50]);    MULADD(at[25], at[49]);    MULADD(at[26], at[48]);    MULADD(at[27], at[47]);    MULADD(at[28], at[46]);    MULADD(at[29], at[45]);    MULADD(at[30], at[44]);    MULADD(at[31], at[43]); 
561    COMBA_STORE(C->dp[42]);
562    /* 43 */
563    COMBA_FORWARD;
564    MULADD(at[12], at[63]);    MULADD(at[13], at[62]);    MULADD(at[14], at[61]);    MULADD(at[15], at[60]);    MULADD(at[16], at[59]);    MULADD(at[17], at[58]);    MULADD(at[18], at[57]);    MULADD(at[19], at[56]);    MULADD(at[20], at[55]);    MULADD(at[21], at[54]);    MULADD(at[22], at[53]);    MULADD(at[23], at[52]);    MULADD(at[24], at[51]);    MULADD(at[25], at[50]);    MULADD(at[26], at[49]);    MULADD(at[27], at[48]);    MULADD(at[28], at[47]);    MULADD(at[29], at[46]);    MULADD(at[30], at[45]);    MULADD(at[31], at[44]); 
565    COMBA_STORE(C->dp[43]);
566    /* 44 */
567    COMBA_FORWARD;
568    MULADD(at[13], at[63]);    MULADD(at[14], at[62]);    MULADD(at[15], at[61]);    MULADD(at[16], at[60]);    MULADD(at[17], at[59]);    MULADD(at[18], at[58]);    MULADD(at[19], at[57]);    MULADD(at[20], at[56]);    MULADD(at[21], at[55]);    MULADD(at[22], at[54]);    MULADD(at[23], at[53]);    MULADD(at[24], at[52]);    MULADD(at[25], at[51]);    MULADD(at[26], at[50]);    MULADD(at[27], at[49]);    MULADD(at[28], at[48]);    MULADD(at[29], at[47]);    MULADD(at[30], at[46]);    MULADD(at[31], at[45]); 
569    COMBA_STORE(C->dp[44]);
570    /* 45 */
571    COMBA_FORWARD;
572    MULADD(at[14], at[63]);    MULADD(at[15], at[62]);    MULADD(at[16], at[61]);    MULADD(at[17], at[60]);    MULADD(at[18], at[59]);    MULADD(at[19], at[58]);    MULADD(at[20], at[57]);    MULADD(at[21], at[56]);    MULADD(at[22], at[55]);    MULADD(at[23], at[54]);    MULADD(at[24], at[53]);    MULADD(at[25], at[52]);    MULADD(at[26], at[51]);    MULADD(at[27], at[50]);    MULADD(at[28], at[49]);    MULADD(at[29], at[48]);    MULADD(at[30], at[47]);    MULADD(at[31], at[46]); 
573    COMBA_STORE(C->dp[45]);
574    /* 46 */
575    COMBA_FORWARD;
576    MULADD(at[15], at[63]);    MULADD(at[16], at[62]);    MULADD(at[17], at[61]);    MULADD(at[18], at[60]);    MULADD(at[19], at[59]);    MULADD(at[20], at[58]);    MULADD(at[21], at[57]);    MULADD(at[22], at[56]);    MULADD(at[23], at[55]);    MULADD(at[24], at[54]);    MULADD(at[25], at[53]);    MULADD(at[26], at[52]);    MULADD(at[27], at[51]);    MULADD(at[28], at[50]);    MULADD(at[29], at[49]);    MULADD(at[30], at[48]);    MULADD(at[31], at[47]); 
577    COMBA_STORE(C->dp[46]);
578    /* 47 */
579    COMBA_FORWARD;
580    MULADD(at[16], at[63]);    MULADD(at[17], at[62]);    MULADD(at[18], at[61]);    MULADD(at[19], at[60]);    MULADD(at[20], at[59]);    MULADD(at[21], at[58]);    MULADD(at[22], at[57]);    MULADD(at[23], at[56]);    MULADD(at[24], at[55]);    MULADD(at[25], at[54]);    MULADD(at[26], at[53]);    MULADD(at[27], at[52]);    MULADD(at[28], at[51]);    MULADD(at[29], at[50]);    MULADD(at[30], at[49]);    MULADD(at[31], at[48]); 
581    COMBA_STORE(C->dp[47]);
582    /* 48 */
583    COMBA_FORWARD;
584    MULADD(at[17], at[63]);    MULADD(at[18], at[62]);    MULADD(at[19], at[61]);    MULADD(at[20], at[60]);    MULADD(at[21], at[59]);    MULADD(at[22], at[58]);    MULADD(at[23], at[57]);    MULADD(at[24], at[56]);    MULADD(at[25], at[55]);    MULADD(at[26], at[54]);    MULADD(at[27], at[53]);    MULADD(at[28], at[52]);    MULADD(at[29], at[51]);    MULADD(at[30], at[50]);    MULADD(at[31], at[49]); 
585    COMBA_STORE(C->dp[48]);
586    /* 49 */
587    COMBA_FORWARD;
588    MULADD(at[18], at[63]);    MULADD(at[19], at[62]);    MULADD(at[20], at[61]);    MULADD(at[21], at[60]);    MULADD(at[22], at[59]);    MULADD(at[23], at[58]);    MULADD(at[24], at[57]);    MULADD(at[25], at[56]);    MULADD(at[26], at[55]);    MULADD(at[27], at[54]);    MULADD(at[28], at[53]);    MULADD(at[29], at[52]);    MULADD(at[30], at[51]);    MULADD(at[31], at[50]); 
589    COMBA_STORE(C->dp[49]);
590    /* 50 */
591    COMBA_FORWARD;
592    MULADD(at[19], at[63]);    MULADD(at[20], at[62]);    MULADD(at[21], at[61]);    MULADD(at[22], at[60]);    MULADD(at[23], at[59]);    MULADD(at[24], at[58]);    MULADD(at[25], at[57]);    MULADD(at[26], at[56]);    MULADD(at[27], at[55]);    MULADD(at[28], at[54]);    MULADD(at[29], at[53]);    MULADD(at[30], at[52]);    MULADD(at[31], at[51]); 
593    COMBA_STORE(C->dp[50]);
594    /* 51 */
595    COMBA_FORWARD;
596    MULADD(at[20], at[63]);    MULADD(at[21], at[62]);    MULADD(at[22], at[61]);    MULADD(at[23], at[60]);    MULADD(at[24], at[59]);    MULADD(at[25], at[58]);    MULADD(at[26], at[57]);    MULADD(at[27], at[56]);    MULADD(at[28], at[55]);    MULADD(at[29], at[54]);    MULADD(at[30], at[53]);    MULADD(at[31], at[52]); 
597    COMBA_STORE(C->dp[51]);
598    /* 52 */
599    COMBA_FORWARD;
600    MULADD(at[21], at[63]);    MULADD(at[22], at[62]);    MULADD(at[23], at[61]);    MULADD(at[24], at[60]);    MULADD(at[25], at[59]);    MULADD(at[26], at[58]);    MULADD(at[27], at[57]);    MULADD(at[28], at[56]);    MULADD(at[29], at[55]);    MULADD(at[30], at[54]);    MULADD(at[31], at[53]); 
601    COMBA_STORE(C->dp[52]);
602    /* 53 */
603    COMBA_FORWARD;
604    MULADD(at[22], at[63]);    MULADD(at[23], at[62]);    MULADD(at[24], at[61]);    MULADD(at[25], at[60]);    MULADD(at[26], at[59]);    MULADD(at[27], at[58]);    MULADD(at[28], at[57]);    MULADD(at[29], at[56]);    MULADD(at[30], at[55]);    MULADD(at[31], at[54]); 
605    COMBA_STORE(C->dp[53]);
606    /* 54 */
607    COMBA_FORWARD;
608    MULADD(at[23], at[63]);    MULADD(at[24], at[62]);    MULADD(at[25], at[61]);    MULADD(at[26], at[60]);    MULADD(at[27], at[59]);    MULADD(at[28], at[58]);    MULADD(at[29], at[57]);    MULADD(at[30], at[56]);    MULADD(at[31], at[55]); 
609    COMBA_STORE(C->dp[54]);
610    /* 55 */
611    COMBA_FORWARD;
612    MULADD(at[24], at[63]);    MULADD(at[25], at[62]);    MULADD(at[26], at[61]);    MULADD(at[27], at[60]);    MULADD(at[28], at[59]);    MULADD(at[29], at[58]);    MULADD(at[30], at[57]);    MULADD(at[31], at[56]); 
613    COMBA_STORE(C->dp[55]);
614    /* 56 */
615    COMBA_FORWARD;
616    MULADD(at[25], at[63]);    MULADD(at[26], at[62]);    MULADD(at[27], at[61]);    MULADD(at[28], at[60]);    MULADD(at[29], at[59]);    MULADD(at[30], at[58]);    MULADD(at[31], at[57]); 
617    COMBA_STORE(C->dp[56]);
618    /* 57 */
619    COMBA_FORWARD;
620    MULADD(at[26], at[63]);    MULADD(at[27], at[62]);    MULADD(at[28], at[61]);    MULADD(at[29], at[60]);    MULADD(at[30], at[59]);    MULADD(at[31], at[58]); 
621    COMBA_STORE(C->dp[57]);
622    /* 58 */
623    COMBA_FORWARD;
624    MULADD(at[27], at[63]);    MULADD(at[28], at[62]);    MULADD(at[29], at[61]);    MULADD(at[30], at[60]);    MULADD(at[31], at[59]); 
625    COMBA_STORE(C->dp[58]);
626    /* 59 */
627    COMBA_FORWARD;
628    MULADD(at[28], at[63]);    MULADD(at[29], at[62]);    MULADD(at[30], at[61]);    MULADD(at[31], at[60]); 
629    COMBA_STORE(C->dp[59]);
630    /* 60 */
631    COMBA_FORWARD;
632    MULADD(at[29], at[63]);    MULADD(at[30], at[62]);    MULADD(at[31], at[61]); 
633    COMBA_STORE(C->dp[60]);
634    /* 61 */
635    COMBA_FORWARD;
636    MULADD(at[30], at[63]);    MULADD(at[31], at[62]); 
637    COMBA_STORE(C->dp[61]);
638    /* 62 */
639    COMBA_FORWARD;
640    MULADD(at[31], at[63]); 
641    COMBA_STORE(C->dp[62]);
642    COMBA_STORE2(C->dp[63]);
643    C->used = 64;
644    C->sign = A->sign ^ B->sign;
645    mp_clamp(C);
646    COMBA_FINI;
647 }
648
649
650
651 void s_mp_sqr_comba_4(const mp_int *A, mp_int *B)
652 {
653    mp_digit *a, b[8], c0, c1, c2;
654
655    a = A->dp;
656    COMBA_START; 
657
658    /* clear carries */
659    CLEAR_CARRY;
660
661    /* output 0 */
662    SQRADD(a[0],a[0]);
663    COMBA_STORE(b[0]);
664
665    /* output 1 */
666    CARRY_FORWARD;
667    SQRADD2(a[0], a[1]); 
668    COMBA_STORE(b[1]);
669
670    /* output 2 */
671    CARRY_FORWARD;
672    SQRADD2(a[0], a[2]);    SQRADD(a[1], a[1]); 
673    COMBA_STORE(b[2]);
674
675    /* output 3 */
676    CARRY_FORWARD;
677    SQRADD2(a[0], a[3]);    SQRADD2(a[1], a[2]); 
678    COMBA_STORE(b[3]);
679
680    /* output 4 */
681    CARRY_FORWARD;
682    SQRADD2(a[1], a[3]);    SQRADD(a[2], a[2]); 
683    COMBA_STORE(b[4]);
684
685    /* output 5 */
686    CARRY_FORWARD;
687    SQRADD2(a[2], a[3]); 
688    COMBA_STORE(b[5]);
689
690    /* output 6 */
691    CARRY_FORWARD;
692    SQRADD(a[3], a[3]); 
693    COMBA_STORE(b[6]);
694    COMBA_STORE2(b[7]);
695    COMBA_FINI;
696
697    B->used = 8;
698    B->sign = ZPOS;
699    memcpy(B->dp, b, 8 * sizeof(mp_digit));
700    mp_clamp(B);
701 }
702
703 void s_mp_sqr_comba_8(const mp_int *A, mp_int *B)
704 {
705    mp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2;
706
707    a = A->dp;
708    COMBA_START; 
709
710    /* clear carries */
711    CLEAR_CARRY;
712
713    /* output 0 */
714    SQRADD(a[0],a[0]);
715    COMBA_STORE(b[0]);
716
717    /* output 1 */
718    CARRY_FORWARD;
719    SQRADD2(a[0], a[1]); 
720    COMBA_STORE(b[1]);
721
722    /* output 2 */
723    CARRY_FORWARD;
724    SQRADD2(a[0], a[2]);    SQRADD(a[1], a[1]); 
725    COMBA_STORE(b[2]);
726
727    /* output 3 */
728    CARRY_FORWARD;
729    SQRADD2(a[0], a[3]);    SQRADD2(a[1], a[2]); 
730    COMBA_STORE(b[3]);
731
732    /* output 4 */
733    CARRY_FORWARD;
734    SQRADD2(a[0], a[4]);    SQRADD2(a[1], a[3]);    SQRADD(a[2], a[2]); 
735    COMBA_STORE(b[4]);
736
737    /* output 5 */
738    CARRY_FORWARD;
739    SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; 
740    COMBA_STORE(b[5]);
741
742    /* output 6 */
743    CARRY_FORWARD;
744    SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); 
745    COMBA_STORE(b[6]);
746
747    /* output 7 */
748    CARRY_FORWARD;
749    SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; 
750    COMBA_STORE(b[7]);
751
752    /* output 8 */
753    CARRY_FORWARD;
754    SQRADDSC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); 
755    COMBA_STORE(b[8]);
756
757    /* output 9 */
758    CARRY_FORWARD;
759    SQRADDSC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; 
760    COMBA_STORE(b[9]);
761
762    /* output 10 */
763    CARRY_FORWARD;
764    SQRADD2(a[3], a[7]);    SQRADD2(a[4], a[6]);    SQRADD(a[5], a[5]); 
765    COMBA_STORE(b[10]);
766
767    /* output 11 */
768    CARRY_FORWARD;
769    SQRADD2(a[4], a[7]);    SQRADD2(a[5], a[6]); 
770    COMBA_STORE(b[11]);
771
772    /* output 12 */
773    CARRY_FORWARD;
774    SQRADD2(a[5], a[7]);    SQRADD(a[6], a[6]); 
775    COMBA_STORE(b[12]);
776
777    /* output 13 */
778    CARRY_FORWARD;
779    SQRADD2(a[6], a[7]); 
780    COMBA_STORE(b[13]);
781
782    /* output 14 */
783    CARRY_FORWARD;
784    SQRADD(a[7], a[7]); 
785    COMBA_STORE(b[14]);
786    COMBA_STORE2(b[15]);
787    COMBA_FINI;
788
789    B->used = 16;
790    B->sign = ZPOS;
791    memcpy(B->dp, b, 16 * sizeof(mp_digit));
792    mp_clamp(B);
793 }
794
795 void s_mp_sqr_comba_16(const mp_int *A, mp_int *B)
796 {
797    mp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;
798
799    a = A->dp;
800    COMBA_START; 
801
802    /* clear carries */
803    CLEAR_CARRY;
804
805    /* output 0 */
806    SQRADD(a[0],a[0]);
807    COMBA_STORE(b[0]);
808
809    /* output 1 */
810    CARRY_FORWARD;
811    SQRADD2(a[0], a[1]); 
812    COMBA_STORE(b[1]);
813
814    /* output 2 */
815    CARRY_FORWARD;
816    SQRADD2(a[0], a[2]);    SQRADD(a[1], a[1]); 
817    COMBA_STORE(b[2]);
818
819    /* output 3 */
820    CARRY_FORWARD;
821    SQRADD2(a[0], a[3]);    SQRADD2(a[1], a[2]); 
822    COMBA_STORE(b[3]);
823
824    /* output 4 */
825    CARRY_FORWARD;
826    SQRADD2(a[0], a[4]);    SQRADD2(a[1], a[3]);    SQRADD(a[2], a[2]); 
827    COMBA_STORE(b[4]);
828
829    /* output 5 */
830    CARRY_FORWARD;
831    SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; 
832    COMBA_STORE(b[5]);
833
834    /* output 6 */
835    CARRY_FORWARD;
836    SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); 
837    COMBA_STORE(b[6]);
838
839    /* output 7 */
840    CARRY_FORWARD;
841    SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; 
842    COMBA_STORE(b[7]);
843
844    /* output 8 */
845    CARRY_FORWARD;
846    SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); 
847    COMBA_STORE(b[8]);
848
849    /* output 9 */
850    CARRY_FORWARD;
851    SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; 
852    COMBA_STORE(b[9]);
853
854    /* output 10 */
855    CARRY_FORWARD;
856    SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); 
857    COMBA_STORE(b[10]);
858
859    /* output 11 */
860    CARRY_FORWARD;
861    SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; 
862    COMBA_STORE(b[11]);
863
864    /* output 12 */
865    CARRY_FORWARD;
866    SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); 
867    COMBA_STORE(b[12]);
868
869    /* output 13 */
870    CARRY_FORWARD;
871    SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; 
872    COMBA_STORE(b[13]);
873
874    /* output 14 */
875    CARRY_FORWARD;
876    SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); 
877    COMBA_STORE(b[14]);
878
879    /* output 15 */
880    CARRY_FORWARD;
881    SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; 
882    COMBA_STORE(b[15]);
883
884    /* output 16 */
885    CARRY_FORWARD;
886    SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); 
887    COMBA_STORE(b[16]);
888
889    /* output 17 */
890    CARRY_FORWARD;
891    SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; 
892    COMBA_STORE(b[17]);
893
894    /* output 18 */
895    CARRY_FORWARD;
896    SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); 
897    COMBA_STORE(b[18]);
898
899    /* output 19 */
900    CARRY_FORWARD;
901    SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; 
902    COMBA_STORE(b[19]);
903
904    /* output 20 */
905    CARRY_FORWARD;
906    SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); 
907    COMBA_STORE(b[20]);
908
909    /* output 21 */
910    CARRY_FORWARD;
911    SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; 
912    COMBA_STORE(b[21]);
913
914    /* output 22 */
915    CARRY_FORWARD;
916    SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); 
917    COMBA_STORE(b[22]);
918
919    /* output 23 */
920    CARRY_FORWARD;
921    SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; 
922    COMBA_STORE(b[23]);
923
924    /* output 24 */
925    CARRY_FORWARD;
926    SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); 
927    COMBA_STORE(b[24]);
928
929    /* output 25 */
930    CARRY_FORWARD;
931    SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; 
932    COMBA_STORE(b[25]);
933
934    /* output 26 */
935    CARRY_FORWARD;
936    SQRADD2(a[11], a[15]);    SQRADD2(a[12], a[14]);    SQRADD(a[13], a[13]); 
937    COMBA_STORE(b[26]);
938
939    /* output 27 */
940    CARRY_FORWARD;
941    SQRADD2(a[12], a[15]);    SQRADD2(a[13], a[14]); 
942    COMBA_STORE(b[27]);
943
944    /* output 28 */
945    CARRY_FORWARD;
946    SQRADD2(a[13], a[15]);    SQRADD(a[14], a[14]); 
947    COMBA_STORE(b[28]);
948
949    /* output 29 */
950    CARRY_FORWARD;
951    SQRADD2(a[14], a[15]); 
952    COMBA_STORE(b[29]);
953
954    /* output 30 */
955    CARRY_FORWARD;
956    SQRADD(a[15], a[15]); 
957    COMBA_STORE(b[30]);
958    COMBA_STORE2(b[31]);
959    COMBA_FINI;
960
961    B->used = 32;
962    B->sign = ZPOS;
963    memcpy(B->dp, b, 32 * sizeof(mp_digit));
964    mp_clamp(B);
965 }
966
967
968 void s_mp_sqr_comba_32(const mp_int *A, mp_int *B)
969 {
970    mp_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2;
971
972    a = A->dp;
973    COMBA_START; 
974
975    /* clear carries */
976    CLEAR_CARRY;
977
978    /* output 0 */
979    SQRADD(a[0],a[0]);
980    COMBA_STORE(b[0]);
981
982    /* output 1 */
983    CARRY_FORWARD;
984    SQRADD2(a[0], a[1]); 
985    COMBA_STORE(b[1]);
986
987    /* output 2 */
988    CARRY_FORWARD;
989    SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); 
990    COMBA_STORE(b[2]);
991
992    /* output 3 */
993    CARRY_FORWARD;
994    SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); 
995    COMBA_STORE(b[3]);
996
997    /* output 4 */
998    CARRY_FORWARD;
999    SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); 
1000    COMBA_STORE(b[4]);
1001
1002    /* output 5 */
1003    CARRY_FORWARD;
1004    SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; 
1005    COMBA_STORE(b[5]);
1006
1007    /* output 6 */
1008    CARRY_FORWARD;
1009    SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); 
1010    COMBA_STORE(b[6]);
1011
1012    /* output 7 */
1013    CARRY_FORWARD;
1014    SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; 
1015    COMBA_STORE(b[7]);
1016
1017    /* output 8 */
1018    CARRY_FORWARD;
1019    SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); 
1020    COMBA_STORE(b[8]);
1021
1022    /* output 9 */
1023    CARRY_FORWARD;
1024    SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; 
1025    COMBA_STORE(b[9]);
1026
1027    /* output 10 */
1028    CARRY_FORWARD;
1029    SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); 
1030    COMBA_STORE(b[10]);
1031
1032    /* output 11 */
1033    CARRY_FORWARD;
1034    SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; 
1035    COMBA_STORE(b[11]);
1036
1037    /* output 12 */
1038    CARRY_FORWARD;
1039    SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); 
1040    COMBA_STORE(b[12]);
1041
1042    /* output 13 */
1043    CARRY_FORWARD;
1044    SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; 
1045    COMBA_STORE(b[13]);
1046
1047    /* output 14 */
1048    CARRY_FORWARD;
1049    SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); 
1050    COMBA_STORE(b[14]);
1051
1052    /* output 15 */
1053    CARRY_FORWARD;
1054    SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; 
1055    COMBA_STORE(b[15]);
1056
1057    /* output 16 */
1058    CARRY_FORWARD;
1059    SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); 
1060    COMBA_STORE(b[16]);
1061
1062    /* output 17 */
1063    CARRY_FORWARD;
1064    SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; 
1065    COMBA_STORE(b[17]);
1066
1067    /* output 18 */
1068    CARRY_FORWARD;
1069    SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); 
1070    COMBA_STORE(b[18]);
1071
1072    /* output 19 */
1073    CARRY_FORWARD;
1074    SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; 
1075    COMBA_STORE(b[19]);
1076
1077    /* output 20 */
1078    CARRY_FORWARD;
1079    SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); 
1080    COMBA_STORE(b[20]);
1081
1082    /* output 21 */
1083    CARRY_FORWARD;
1084    SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; 
1085    COMBA_STORE(b[21]);
1086
1087    /* output 22 */
1088    CARRY_FORWARD;
1089    SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); 
1090    COMBA_STORE(b[22]);
1091
1092    /* output 23 */
1093    CARRY_FORWARD;
1094    SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; 
1095    COMBA_STORE(b[23]);
1096
1097    /* output 24 */
1098    CARRY_FORWARD;
1099    SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); 
1100    COMBA_STORE(b[24]);
1101
1102    /* output 25 */
1103    CARRY_FORWARD;
1104    SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; 
1105    COMBA_STORE(b[25]);
1106
1107    /* output 26 */
1108    CARRY_FORWARD;
1109    SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); 
1110    COMBA_STORE(b[26]);
1111
1112    /* output 27 */
1113    CARRY_FORWARD;
1114    SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; 
1115    COMBA_STORE(b[27]);
1116
1117    /* output 28 */
1118    CARRY_FORWARD;
1119    SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); 
1120    COMBA_STORE(b[28]);
1121
1122    /* output 29 */
1123    CARRY_FORWARD;
1124    SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; 
1125    COMBA_STORE(b[29]);
1126
1127    /* output 30 */
1128    CARRY_FORWARD;
1129    SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); 
1130    COMBA_STORE(b[30]);
1131
1132    /* output 31 */
1133    CARRY_FORWARD;
1134    SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; 
1135    COMBA_STORE(b[31]);
1136
1137    /* output 32 */
1138    CARRY_FORWARD;
1139    SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); 
1140    COMBA_STORE(b[32]);
1141
1142    /* output 33 */
1143    CARRY_FORWARD;
1144    SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; 
1145    COMBA_STORE(b[33]);
1146
1147    /* output 34 */
1148    CARRY_FORWARD;
1149    SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); 
1150    COMBA_STORE(b[34]);
1151
1152    /* output 35 */
1153    CARRY_FORWARD;
1154    SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; 
1155    COMBA_STORE(b[35]);
1156
1157    /* output 36 */
1158    CARRY_FORWARD;
1159    SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); 
1160    COMBA_STORE(b[36]);
1161
1162    /* output 37 */
1163    CARRY_FORWARD;
1164    SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; 
1165    COMBA_STORE(b[37]);
1166
1167    /* output 38 */
1168    CARRY_FORWARD;
1169    SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); 
1170    COMBA_STORE(b[38]);
1171
1172    /* output 39 */
1173    CARRY_FORWARD;
1174    SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; 
1175    COMBA_STORE(b[39]);
1176
1177    /* output 40 */
1178    CARRY_FORWARD;
1179    SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); 
1180    COMBA_STORE(b[40]);
1181
1182    /* output 41 */
1183    CARRY_FORWARD;
1184    SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; 
1185    COMBA_STORE(b[41]);
1186
1187    /* output 42 */
1188    CARRY_FORWARD;
1189    SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]); 
1190    COMBA_STORE(b[42]);
1191
1192    /* output 43 */
1193    CARRY_FORWARD;
1194    SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB; 
1195    COMBA_STORE(b[43]);
1196
1197    /* output 44 */
1198    CARRY_FORWARD;
1199    SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]); 
1200    COMBA_STORE(b[44]);
1201
1202    /* output 45 */
1203    CARRY_FORWARD;
1204    SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB; 
1205    COMBA_STORE(b[45]);
1206
1207    /* output 46 */
1208    CARRY_FORWARD;
1209    SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]); 
1210    COMBA_STORE(b[46]);
1211
1212    /* output 47 */
1213    CARRY_FORWARD;
1214    SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; 
1215    COMBA_STORE(b[47]);
1216
1217    /* output 48 */
1218    CARRY_FORWARD;
1219    SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); 
1220    COMBA_STORE(b[48]);
1221
1222    /* output 49 */
1223    CARRY_FORWARD;
1224    SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; 
1225    COMBA_STORE(b[49]);
1226
1227    /* output 50 */
1228    CARRY_FORWARD;
1229    SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]); 
1230    COMBA_STORE(b[50]);
1231
1232    /* output 51 */
1233    CARRY_FORWARD;
1234    SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB; 
1235    COMBA_STORE(b[51]);
1236
1237    /* output 52 */
1238    CARRY_FORWARD;
1239    SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]); 
1240    COMBA_STORE(b[52]);
1241
1242    /* output 53 */
1243    CARRY_FORWARD;
1244    SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB; 
1245    COMBA_STORE(b[53]);
1246
1247    /* output 54 */
1248    CARRY_FORWARD;
1249    SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]); 
1250    COMBA_STORE(b[54]);
1251
1252    /* output 55 */
1253    CARRY_FORWARD;
1254    SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB; 
1255    COMBA_STORE(b[55]);
1256
1257    /* output 56 */
1258    CARRY_FORWARD;
1259    SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]); 
1260    COMBA_STORE(b[56]);
1261
1262    /* output 57 */
1263    CARRY_FORWARD;
1264    SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB; 
1265    COMBA_STORE(b[57]);
1266
1267    /* output 58 */
1268    CARRY_FORWARD;
1269    SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]); 
1270    COMBA_STORE(b[58]);
1271
1272    /* output 59 */
1273    CARRY_FORWARD;
1274    SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]); 
1275    COMBA_STORE(b[59]);
1276
1277    /* output 60 */
1278    CARRY_FORWARD;
1279    SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]); 
1280    COMBA_STORE(b[60]);
1281
1282    /* output 61 */
1283    CARRY_FORWARD;
1284    SQRADD2(a[30], a[31]); 
1285    COMBA_STORE(b[61]);
1286
1287    /* output 62 */
1288    CARRY_FORWARD;
1289    SQRADD(a[31], a[31]); 
1290    COMBA_STORE(b[62]);
1291    COMBA_STORE2(b[63]);
1292    COMBA_FINI;
1293
1294    B->used = 64;
1295    B->sign = ZPOS;
1296    memcpy(B->dp, b, 64 * sizeof(mp_digit));
1297    mp_clamp(B);
1298 }