1 /* Start: fp_2expt.c */
2 /* TomsFastMath, a fast ISO C bignum library.
4 * This project is meant to fill in where LibTomMath
5 * falls short. That is speed ;-)
7 * This project is public domain and free for all purposes.
9 * Tom St Denis, tomstdenis@iahu.ca
13 /* computes a = 2**b */
14 void fp_2expt(fp_int *a, int b)
18 /* zero a as per default */
30 /* set the used count of where the bit will go */
33 /* put the single bit in its place */
34 a->dp[z] = ((fp_digit)1) << (b % DIGIT_BIT);
41 /* TomsFastMath, a fast ISO C bignum library.
43 * This project is meant to fill in where LibTomMath
44 * falls short. That is speed ;-)
46 * This project is public domain and free for all purposes.
48 * Tom St Denis, tomstdenis@iahu.ca
52 void fp_add(fp_int *a, fp_int *b, fp_int *c)
56 /* get sign of both inputs */
60 /* handle two cases, not four */
62 /* both positive or both negative */
63 /* add their magnitudes, copy the sign */
67 /* one positive, the other negative */
68 /* subtract the one with the greater magnitude from */
69 /* the one of the lesser magnitude. The result gets */
70 /* the sign of the one with the greater magnitude. */
71 if (fp_cmp_mag (a, b) == FP_LT) {
83 /* Start: fp_add_d.c */
84 /* TomsFastMath, a fast ISO C bignum library.
86 * This project is meant to fill in where LibTomMath
87 * falls short. That is speed ;-)
89 * This project is public domain and free for all purposes.
91 * Tom St Denis, tomstdenis@iahu.ca
96 void fp_add_d(fp_int *a, fp_digit b, fp_int *c)
103 /* End: fp_add_d.c */
105 /* Start: fp_addmod.c */
106 /* TomsFastMath, a fast ISO C bignum library.
108 * This project is meant to fill in where LibTomMath
109 * falls short. That is speed ;-)
111 * This project is public domain and free for all purposes.
113 * Tom St Denis, tomstdenis@iahu.ca
117 /* d = a + b (mod c) */
118 int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
123 return fp_mod(&tmp, c, d);
126 /* End: fp_addmod.c */
128 /* Start: fp_cmp.c */
129 /* TomsFastMath, a fast ISO C bignum library.
131 * This project is meant to fill in where LibTomMath
132 * falls short. That is speed ;-)
134 * This project is public domain and free for all purposes.
136 * Tom St Denis, tomstdenis@iahu.ca
140 int fp_cmp(fp_int *a, fp_int *b)
142 if (a->sign == FP_NEG && b->sign == FP_ZPOS) {
144 } else if (a->sign == FP_ZPOS && b->sign == FP_NEG) {
148 if (a->sign == FP_NEG) {
149 /* if negative compare opposite direction */
150 return fp_cmp_mag(b, a);
152 return fp_cmp_mag(a, b);
159 /* Start: fp_cmp_d.c */
160 /* TomsFastMath, a fast ISO C bignum library.
162 * This project is meant to fill in where LibTomMath
163 * falls short. That is speed ;-)
165 * This project is public domain and free for all purposes.
167 * Tom St Denis, tomstdenis@iahu.ca
171 /* compare against a single digit */
172 int fp_cmp_d(fp_int *a, fp_digit b)
174 /* compare based on sign */
175 if ((b && a->used == 0) || a->sign == FP_NEG) {
179 /* compare based on magnitude */
184 /* compare the only digit of a to b */
187 } else if (a->dp[0] < b) {
195 /* End: fp_cmp_d.c */
197 /* Start: fp_cmp_mag.c */
198 /* TomsFastMath, a fast ISO C bignum library.
200 * This project is meant to fill in where LibTomMath
201 * falls short. That is speed ;-)
203 * This project is public domain and free for all purposes.
205 * Tom St Denis, tomstdenis@iahu.ca
209 int fp_cmp_mag(fp_int *a, fp_int *b)
213 if (a->used > b->used) {
215 } else if (a->used < b->used) {
218 for (x = a->used - 1; x >= 0; x--) {
219 if (a->dp[x] > b->dp[x]) {
221 } else if (a->dp[x] < b->dp[x]) {
230 /* End: fp_cmp_mag.c */
232 /* Start: fp_cnt_lsb.c */
233 /* TomsFastMath, a fast ISO C bignum library.
235 * This project is meant to fill in where LibTomMath
236 * falls short. That is speed ;-)
238 * This project is public domain and free for all purposes.
240 * Tom St Denis, tomstdenis@iahu.ca
244 static const int lnz[16] = {
245 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
248 /* Counts the number of lsbs which are zero before the first zero bit */
249 int fp_cnt_lsb(fp_int *a)
255 if (fp_iszero(a) == 1) {
259 /* scan lower digits until non-zero */
260 for (x = 0; x < a->used && a->dp[x] == 0; x++);
264 /* now scan this digit until a 1 is found */
276 /* End: fp_cnt_lsb.c */
278 /* Start: fp_count_bits.c */
279 /* TomsFastMath, a fast ISO C bignum library.
281 * This project is meant to fill in where LibTomMath
282 * falls short. That is speed ;-)
284 * This project is public domain and free for all purposes.
286 * Tom St Denis, tomstdenis@iahu.ca
290 int fp_count_bits (fp_int * a)
300 /* get number of digits and add that */
301 r = (a->used - 1) * DIGIT_BIT;
303 /* take the last digit and count the bits in it */
304 q = a->dp[a->used - 1];
305 while (q > ((fp_digit) 0)) {
307 q >>= ((fp_digit) 1);
312 /* End: fp_count_bits.c */
314 /* Start: fp_div.c */
315 /* TomsFastMath, a fast ISO C bignum library.
317 * This project is meant to fill in where LibTomMath
318 * falls short. That is speed ;-)
320 * This project is public domain and free for all purposes.
322 * Tom St Denis, tomstdenis@iahu.ca
326 /* a/b => cb + d == a */
327 int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
329 fp_int q, x, y, t1, t2;
330 int n, t, i, norm, neg;
332 /* is divisor zero ? */
333 if (fp_iszero (b) == 1) {
337 /* if a < b then q=0, r = a */
338 if (fp_cmp_mag (a, b) == FP_LT) {
349 q.used = a->used + 2;
357 neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG;
358 x.sign = y.sign = FP_ZPOS;
360 /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
361 norm = fp_count_bits(&y) % DIGIT_BIT;
362 if (norm < (int)(DIGIT_BIT-1)) {
363 norm = (DIGIT_BIT-1) - norm;
364 fp_mul_2d (&x, norm, &x);
365 fp_mul_2d (&y, norm, &y);
370 /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
374 /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
375 fp_lshd (&y, n - t); /* y = y*b**{n-t} */
377 while (fp_cmp (&x, &y) != FP_LT) {
382 /* reset y by shifting it back down */
385 /* step 3. for i from n down to (t + 1) */
386 for (i = n; i >= (t + 1); i--) {
391 /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
392 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
393 if (x.dp[i] == y.dp[t]) {
394 q.dp[i - t - 1] = ((((fp_word)1) << DIGIT_BIT) - 1);
397 tmp = ((fp_word) x.dp[i]) << ((fp_word) DIGIT_BIT);
398 tmp |= ((fp_word) x.dp[i - 1]);
399 tmp /= ((fp_word) y.dp[t]);
400 q.dp[i - t - 1] = (fp_digit) (tmp);
403 /* while (q{i-t-1} * (yt * b + y{t-1})) >
404 xi * b**2 + xi-1 * b + xi-2
408 q.dp[i - t - 1] = (q.dp[i - t - 1] + 1);
410 q.dp[i - t - 1] = (q.dp[i - t - 1] - 1);
414 t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
417 fp_mul_d (&t1, q.dp[i - t - 1], &t1);
419 /* find right hand */
420 t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
421 t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
424 } while (fp_cmp_mag(&t1, &t2) == FP_GT);
426 /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
427 fp_mul_d (&y, q.dp[i - t - 1], &t1);
428 fp_lshd (&t1, i - t - 1);
429 fp_sub (&x, &t1, &x);
431 /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
432 if (x.sign == FP_NEG) {
434 fp_lshd (&t1, i - t - 1);
435 fp_add (&x, &t1, &x);
436 q.dp[i - t - 1] = q.dp[i - t - 1] - 1;
440 /* now q is the quotient and x is the remainder
441 * [which we have to normalize]
444 /* get sign before writing to c */
445 x.sign = x.used == 0 ? FP_ZPOS : a->sign;
454 fp_div_2d (&x, norm, &x, NULL);
456 /* the following is a kludge, essentially we were seeing the right remainder but
457 with excess digits that should have been zero
459 for (i = b->used; i < x.used; i++) {
471 /* Start: fp_div_2.c */
472 /* TomsFastMath, a fast ISO C bignum library.
474 * This project is meant to fill in where LibTomMath
475 * falls short. That is speed ;-)
477 * This project is public domain and free for all purposes.
479 * Tom St Denis, tomstdenis@iahu.ca
484 void fp_div_2(fp_int * a, fp_int * b)
491 register fp_digit r, rr, *tmpa, *tmpb;
494 tmpa = a->dp + b->used - 1;
497 tmpb = b->dp + b->used - 1;
501 for (x = b->used - 1; x >= 0; x--) {
502 /* get the carry for the next iteration */
505 /* shift the current digit, add in carry and store */
506 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
508 /* forward carry to next iteration */
512 /* zero excess digits */
513 tmpb = b->dp + b->used;
514 for (x = b->used; x < oldused; x++) {
522 /* End: fp_div_2.c */
524 /* Start: fp_div_2d.c */
525 /* TomsFastMath, a fast ISO C bignum library.
527 * This project is meant to fill in where LibTomMath
528 * falls short. That is speed ;-)
530 * This project is public domain and free for all purposes.
532 * Tom St Denis, tomstdenis@iahu.ca
537 void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
543 /* if the shift count is <= 0 then we do no work */
554 /* get the remainder */
556 fp_mod_2d (a, b, &t);
562 /* shift by as many digits in the bit count */
563 if (b >= (int)DIGIT_BIT) {
564 fp_rshd (c, b / DIGIT_BIT);
567 /* shift any bit count < DIGIT_BIT */
568 D = (fp_digit) (b % DIGIT_BIT);
570 register fp_digit *tmpc, mask, shift;
573 mask = (((fp_digit)1) << D) - 1;
576 shift = DIGIT_BIT - D;
579 tmpc = c->dp + (c->used - 1);
583 for (x = c->used - 1; x >= 0; x--) {
584 /* get the lower bits of this word in a temp */
587 /* shift the current word and mix in the carry bits from the previous word */
588 *tmpc = (*tmpc >> D) | (r << shift);
591 /* set the carry to the carry bits of the current word found above */
601 /* End: fp_div_2d.c */
603 /* Start: fp_div_d.c */
604 /* TomsFastMath, a fast ISO C bignum library.
606 * This project is meant to fill in where LibTomMath
607 * falls short. That is speed ;-)
609 * This project is public domain and free for all purposes.
611 * Tom St Denis, tomstdenis@iahu.ca
615 static int s_is_power_of_two(fp_digit b, int *p)
619 for (x = 1; x < DIGIT_BIT; x++) {
620 if (b == (((fp_digit)1)<<x)) {
628 /* a/b => cb + d == a */
629 int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d)
636 /* cannot divide by zero */
642 if (b == 1 || fp_iszero(a) == 1) {
653 if (s_is_power_of_two(b, &ix) == 1) {
655 *d = a->dp[0] & ((((fp_digit)1)<<ix) - 1);
658 fp_div_2d(a, ix, c, NULL);
663 /* no easy answer [c'est la vie]. Just division */
669 for (ix = a->used - 1; ix >= 0; ix--) {
670 w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]);
673 t = (fp_digit)(w / b);
674 w -= ((fp_word)t) * ((fp_word)b);
678 q.dp[ix] = (fp_digit)t;
694 /* End: fp_div_d.c */
696 /* Start: fp_exptmod.c */
697 /* TomsFastMath, a fast ISO C bignum library.
699 * This project is meant to fill in where LibTomMath
700 * falls short. That is speed ;-)
702 * This project is public domain and free for all purposes.
704 * Tom St Denis, tomstdenis@iahu.ca
709 * Some restrictions... x must be positive and < b
711 static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
715 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
717 /* find window size */
718 x = fp_count_bits (X);
721 } else if (x <= 36) {
723 } else if (x <= 140) {
725 } else if (x <= 450) {
732 memset(M, 0, sizeof(M));
734 /* now setup montgomery */
735 if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {
744 * The M table contains powers of the input base, e.g. M[x] = G^x mod P
746 * The first half of the table is not computed though accept for M[0] and M[1]
749 /* now we need R mod m */
750 fp_montgomery_calc_normalization (&res, P);
752 /* now set M[1] to G * R mod m */
753 if (fp_cmp_mag(P, G) != FP_GT) {
754 /* G > P so we reduce it first */
759 fp_mulmod (&M[1], &res, P, &M[1]);
761 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
762 fp_copy (&M[1], &M[1 << (winsize - 1)]);
763 for (x = 0; x < (winsize - 1); x++) {
764 fp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)]);
765 fp_montgomery_reduce (&M[1 << (winsize - 1)], P, mp);
768 /* create upper table */
769 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
770 fp_mul(&M[x - 1], &M[1], &M[x]);
771 fp_montgomery_reduce(&M[x], P, mp);
774 /* set initial mode and bit cnt */
778 digidx = X->used - 1;
783 /* grab next digit as required */
785 /* if digidx == -1 we are out of digits so break */
789 /* read next digit and reset bitcnt */
790 buf = X->dp[digidx--];
791 bitcnt = (int)DIGIT_BIT;
794 /* grab the next msb from the exponent */
795 y = (fp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
798 /* if the bit is zero and mode == 0 then we ignore it
799 * These represent the leading zero bits before the first 1 bit
800 * in the exponent. Technically this opt is not required but it
801 * does lower the # of trivial squaring/reductions used
803 if (mode == 0 && y == 0) {
807 /* if the bit is zero and mode == 1 then we square */
808 if (mode == 1 && y == 0) {
810 fp_montgomery_reduce(&res, P, mp);
814 /* else we add it to the window */
815 bitbuf |= (y << (winsize - ++bitcpy));
818 if (bitcpy == winsize) {
819 /* ok window is filled so square as required and multiply */
821 for (x = 0; x < winsize; x++) {
823 fp_montgomery_reduce(&res, P, mp);
827 fp_mul(&res, &M[bitbuf], &res);
828 fp_montgomery_reduce(&res, P, mp);
830 /* empty window and reset */
837 /* if bits remain then square/multiply */
838 if (mode == 2 && bitcpy > 0) {
839 /* square then multiply if the bit is set */
840 for (x = 0; x < bitcpy; x++) {
842 fp_montgomery_reduce(&res, P, mp);
844 /* get next bit of the window */
846 if ((bitbuf & (1 << winsize)) != 0) {
848 fp_mul(&res, &M[1], &res);
849 fp_montgomery_reduce(&res, P, mp);
854 /* fixup result if Montgomery reduction is used
855 * recall that any value in a Montgomery system is
856 * actually multiplied by R mod n. So we have
857 * to reduce one more time to cancel out the factor
860 fp_montgomery_reduce(&res, P, mp);
862 /* swap res with Y */
868 int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
874 if (X->sign == FP_NEG) {
875 /* yes, copy G and invmod it */
877 if ((err = fp_invmod(&tmp, P, &tmp)) != FP_OKAY) {
881 err = _fp_exptmod(&tmp, X, P, Y);
885 /* Positive exponent so just exptmod */
886 return _fp_exptmod(G, X, P, Y);
890 /* End: fp_exptmod.c */
892 /* Start: fp_gcd.c */
893 /* TomsFastMath, a fast ISO C bignum library.
895 * This project is meant to fill in where LibTomMath
896 * falls short. That is speed ;-)
898 * This project is public domain and free for all purposes.
900 * Tom St Denis, tomstdenis@iahu.ca
905 void fp_gcd(fp_int *a, fp_int *b, fp_int *c)
909 /* either zero than gcd is the largest */
910 if (fp_iszero (a) == 1 && fp_iszero (b) == 0) {
914 if (fp_iszero (a) == 0 && fp_iszero (b) == 1) {
919 /* optimized. At this point if a == 0 then
920 * b must equal zero too
922 if (fp_iszero (a) == 1) {
928 if (fp_cmp_mag(a, b) != FP_LT) {
937 while (fp_iszero(&v) == FP_NO) {
947 /* Start: fp_ident.c */
950 const char *fp_ident(void)
952 static char buf[1024];
954 memset(buf, 0, sizeof(buf));
955 snprintf(buf, sizeof(buf)-1,
956 "TomsFastMath (%s)\n"
995 "\n", __DATE__, sizeof(fp_digit), sizeof(fp_word), FP_MAX_SIZE);
997 if (sizeof(fp_digit) == sizeof(fp_word)) {
998 strncat(buf, "WARNING: sizeof(fp_digit) == sizeof(fp_word), this build is likely to not work properly.\n",
1008 printf("%s\n", fp_ident());
1015 /* End: fp_ident.c */
1017 /* Start: fp_invmod.c */
1018 /* TomsFastMath, a fast ISO C bignum library.
1020 * This project is meant to fill in where LibTomMath
1021 * falls short. That is speed ;-)
1023 * This project is public domain and free for all purposes.
1025 * Tom St Denis, tomstdenis@iahu.ca
1029 /* c = 1/a (mod b) for odd b only */
1030 int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
1032 fp_int x, y, u, v, B, D;
1035 /* 2. [modified] b must be odd */
1036 if (fp_iseven (b) == FP_YES) {
1040 /* init all our temps */
1041 fp_init(&x); fp_init(&y);
1042 fp_init(&u); fp_init(&v);
1043 fp_init(&B); fp_init(&D);
1045 /* x == modulus, y == value to invert */
1048 /* we need y = |a| */
1051 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
1057 /* 4. while u is even do */
1058 while (fp_iseven (&u) == FP_YES) {
1062 /* 4.2 if B is odd then */
1063 if (fp_isodd (&B) == FP_YES) {
1064 fp_sub (&B, &x, &B);
1070 /* 5. while v is even do */
1071 while (fp_iseven (&v) == FP_YES) {
1075 /* 5.2 if D is odd then */
1076 if (fp_isodd (&D) == FP_YES) {
1078 fp_sub (&D, &x, &D);
1084 /* 6. if u >= v then */
1085 if (fp_cmp (&u, &v) != FP_LT) {
1086 /* u = u - v, B = B - D */
1087 fp_sub (&u, &v, &u);
1088 fp_sub (&B, &D, &B);
1090 /* v - v - u, D = D - B */
1091 fp_sub (&v, &u, &v);
1092 fp_sub (&D, &B, &D);
1095 /* if not zero goto step 4 */
1096 if (fp_iszero (&u) == FP_NO) {
1100 /* now a = C, b = D, gcd == g*v */
1102 /* if v != 1 then there is no inverse */
1103 if (fp_cmp_d (&v, 1) != FP_EQ) {
1107 /* b is now the inverse */
1109 while (D.sign == FP_NEG) {
1117 /* End: fp_invmod.c */
1119 /* Start: fp_isprime.c */
1120 /* TomsFastMath, a fast ISO C bignum library.
1122 * This project is meant to fill in where LibTomMath
1123 * falls short. That is speed ;-)
1125 * This project is public domain and free for all purposes.
1127 * Tom St Denis, tomstdenis@iahu.ca
1132 static const fp_digit primes[256] = {
1133 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
1134 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
1135 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
1136 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,
1137 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
1138 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
1139 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
1140 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
1142 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
1143 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
1144 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
1145 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
1146 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
1147 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
1148 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
1149 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
1151 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
1152 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
1153 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
1154 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
1155 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
1156 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
1157 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
1158 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
1160 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
1161 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
1162 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
1163 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
1164 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
1165 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
1166 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
1167 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
1170 int fp_isprime(fp_int *a)
1176 /* do trial division */
1177 for (r = 0; r < 256; r++) {
1178 fp_mod_d(a, primes[r], &d);
1184 /* now do 8 miller rabins */
1185 for (r = 0; r < 8; r++) {
1186 fp_set(&b, primes[r]);
1187 fp_prime_miller_rabin(a, &b, &res);
1195 /* End: fp_isprime.c */
1197 /* Start: fp_lcm.c */
1198 /* TomsFastMath, a fast ISO C bignum library.
1200 * This project is meant to fill in where LibTomMath
1201 * falls short. That is speed ;-)
1203 * This project is public domain and free for all purposes.
1205 * Tom St Denis, tomstdenis@iahu.ca
1210 void fp_lcm(fp_int *a, fp_int *b, fp_int *c)
1217 if (fp_cmp_mag(a, b) == FP_GT) {
1218 fp_div(a, &t1, &t2, NULL);
1221 fp_div(b, &t1, &t2, NULL);
1228 /* Start: fp_lshd.c */
1229 /* TomsFastMath, a fast ISO C bignum library.
1231 * This project is meant to fill in where LibTomMath
1232 * falls short. That is speed ;-)
1234 * This project is public domain and free for all purposes.
1236 * Tom St Denis, tomstdenis@iahu.ca
1240 void fp_lshd(fp_int *a, int x)
1244 /* move up and truncate as required */
1245 y = MIN(a->used + x - 1, (int)(FP_SIZE-1));
1247 /* store new size */
1251 for (; y >= x; y--) {
1252 a->dp[y] = a->dp[y-x];
1255 /* zero lower digits */
1256 for (; y >= 0; y--) {
1264 /* End: fp_lshd.c */
1266 /* Start: fp_mod.c */
1267 /* TomsFastMath, a fast ISO C bignum library.
1269 * This project is meant to fill in where LibTomMath
1270 * falls short. That is speed ;-)
1272 * This project is public domain and free for all purposes.
1274 * Tom St Denis, tomstdenis@iahu.ca
1278 /* c = a mod b, 0 <= c < b */
1279 int fp_mod(fp_int *a, fp_int *b, fp_int *c)
1285 if ((err = fp_div(a, b, NULL, &t)) != FP_OKAY) {
1288 if (t.sign != b->sign) {
1300 /* Start: fp_mod_2d.c */
1301 /* TomsFastMath, a fast ISO C bignum library.
1303 * This project is meant to fill in where LibTomMath
1304 * falls short. That is speed ;-)
1306 * This project is public domain and free for all purposes.
1308 * Tom St Denis, tomstdenis@iahu.ca
1312 /* c = a mod 2**d */
1313 void fp_mod_2d(fp_int *a, int b, fp_int *c)
1317 /* zero if count less than or equal to zero */
1323 /* get copy of input */
1326 /* if 2**d is larger than we just return */
1327 if (b >= (DIGIT_BIT * a->used)) {
1331 /* zero digits above the last digit of the modulus */
1332 for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
1335 /* clear the digit that is not completely outside/inside the modulus */
1336 c->dp[b / DIGIT_BIT] &= ~((fp_digit)0) >> (DIGIT_BIT - b);
1340 /* End: fp_mod_2d.c */
1342 /* Start: fp_mod_d.c */
1343 /* TomsFastMath, a fast ISO C bignum library.
1345 * This project is meant to fill in where LibTomMath
1346 * falls short. That is speed ;-)
1348 * This project is public domain and free for all purposes.
1350 * Tom St Denis, tomstdenis@iahu.ca
1354 /* c = a mod b, 0 <= c < b */
1355 int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
1357 return fp_div_d(a, b, NULL, c);
1360 /* End: fp_mod_d.c */
1362 /* Start: fp_montgomery_calc_normalization.c */
1363 /* TomsFastMath, a fast ISO C bignum library.
1365 * This project is meant to fill in where LibTomMath
1366 * falls short. That is speed ;-)
1368 * This project is public domain and free for all purposes.
1370 * Tom St Denis, tomstdenis@iahu.ca
1374 /* computes a = B**n mod b without division or multiplication useful for
1375 * normalizing numbers in a Montgomery system.
1377 void fp_montgomery_calc_normalization(fp_int *a, fp_int *b)
1381 /* how many bits of last digit does b use */
1382 bits = fp_count_bits (b) % DIGIT_BIT;
1384 /* compute A = B^(n-1) * 2^(bits-1) */
1386 fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1);
1392 /* now compute C = A * B mod b */
1393 for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
1395 if (fp_cmp_mag (a, b) != FP_LT) {
1402 /* End: fp_montgomery_calc_normalization.c */
1404 /* Start: fp_montgomery_reduce.c */
1405 /* TomsFastMath, a fast ISO C bignum library.
1407 * This project is meant to fill in where LibTomMath
1408 * falls short. That is speed ;-)
1410 * This project is public domain and free for all purposes.
1412 * Tom St Denis, tomstdenis@iahu.ca
1416 #if defined(TFM_X86)
1424 #define LOOP_START \
1429 "movl %7,%%eax \n\t" \
1431 "addl %%eax,%0 \n\t" \
1432 "adcl %%edx,%1 \n\t" \
1434 :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \
1435 "g"(mu), "g"(*tmpm++) \
1436 : "%eax", "%edx", "%cc");
1440 "movl %1,%%eax \n\t" \
1441 "addl %%eax,%6 \n\t" \
1442 "movl %2,%%eax \n\t" \
1443 "adcl %%eax,%7 \n\t" \
1445 :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \
1446 "m"(_c[OFF0+1]), "m"(_c[OFF1+1]), "m"(_c[OFF2+1]) \
1449 #elif defined(TFM_X86_64)
1456 #define LOOP_START \
1461 "movq %7,%%rax \n\t" \
1463 "addq %%rax,%0 \n\t" \
1464 "adcq %%rdx,%1 \n\t" \
1466 :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \
1467 "g"(mu), "g"(*tmpm++) \
1468 : "%rax", "%rdx", "%cc");
1472 "movq %1,%%rax \n\t" \
1473 "movq %2,%%rbx \n\t" \
1474 "addq %%rax,%6 \n\t" \
1475 "adcq %%rbx,%7 \n\t" \
1477 :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \
1478 "m"(_c[OFF0+1]), "m"(_c[OFF1+1]), "m"(_c[OFF2+1]) \
1479 : "%rax", "%rbx", "%cc");
1481 #elif defined(TFM_SSE2)
1485 #define MONT_START \
1486 asm("movd %0,%%mm2"::"g"(mp));
1491 #define LOOP_START \
1493 "movd %0,%%mm1 \n\t" \
1494 "pmuludq %%mm2,%%mm1 \n\t" \
1499 "movd %6,%%mm0 \n\t" \
1500 "pmuludq %%mm1,%%mm0 \n\t" \
1501 "movd %%mm0,%%eax \n\t" \
1502 "psrlq $32, %%mm0 \n\t" \
1503 "addl %%eax,%0 \n\t" \
1504 "movd %%mm0,%%eax \n\t" \
1505 "adcl %%eax,%1 \n\t" \
1507 :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \
1513 "movl %1,%%eax \n\t" \
1514 "addl %%eax,%6 \n\t" \
1515 "movl %2,%%eax \n\t" \
1516 "adcl %%eax,%7 \n\t" \
1518 :"=g"(_c[OFF0]), "=g"(_c[OFF1]), "=g"(_c[OFF2]):"0"(_c[OFF0]), "1"(_c[OFF1]), "2"(_c[OFF2]), \
1519 "g"(_c[OFF0+1]), "g"(_c[OFF1+1]), "g"(_c[OFF2+1]) \
1522 #elif defined(TFM_ARM)
1529 #define LOOP_START \
1532 /* NOTE: later write it using two regs instead of three for _c + ... */
1535 "UMULL r0,r1,%0,%1 \n\t" \
1536 "LDR r2,[%2] \n\t" \
1537 "ADDS r2,r2,r0 \n\t" \
1538 "STR r2,[%2] \n\t" \
1539 "LDR r2,[%3] \n\t" \
1540 "ADCS r2,r2,r1 \n\t" \
1541 "STR r2,[%3] \n\t" \
1542 "LDR r2,[%4] \n\t" \
1543 "ADC r2,r2,#0 \n\t" \
1544 "STR r2,[%4] \n\t" \
1545 ::"r"(mu),"r"(*tmpm++),"r"(_c + OFF0),"r"(_c + OFF1),"r"(_c + OFF2):"r0", "r1", "r2", "%cc");
1549 "LDR r0,[%1] \n\t" \
1550 "LDR r1,[%0,#4] \n\t" \
1551 "ADDS r0,r0,r1 \n\t" \
1552 "STR r0,[%0,#4] \n\t" \
1553 "LDR r0,[%2] \n\t" \
1554 "LDR r1,[%1,#4] \n\t" \
1555 "ADCS r0,r0,r1 \n\t" \
1556 "STR r0,[%1,#4] \n\t" \
1557 "LDR r0,[%2,#4] \n\t" \
1558 "ADC r0,r0,#0 \n\t" \
1559 "STR r0,[%2,#4] \n\t" \
1560 ::"r"(_c + OFF0),"r"(_c + OFF1),"r"(_c + OFF2):"r0", "r1", "%cc");
1569 #define LOOP_START \
1574 t = (fp_word)_c[OFF0] + ((fp_word)mu) * ((fp_word)*tmpm++); _c[OFF0] = t; \
1575 t = (fp_word)_c[OFF1] + (t >> DIGIT_BIT); _c[OFF1] = t; \
1576 _c[OFF2] += (t >> DIGIT_BIT); \
1581 t = (fp_word)_c[OFF0+1] + (fp_word)_c[OFF1]; _c[OFF0+1] = t; \
1582 t = (fp_word)_c[OFF1+1] + (t >> DIGIT_BIT) + (fp_word)_c[OFF2]; _c[OFF1+1] = t; \
1583 _c[OFF2+1] += (t >> DIGIT_BIT); \
1590 #define OFF1 (FP_SIZE)
1591 #define OFF2 (FP_SIZE+FP_SIZE)
1593 /* computes x/R == x (mod N) via Montgomery Reduction */
1594 void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp)
1596 fp_digit c[3*FP_SIZE], *_c, *tmpm, mu;
1597 int oldused, x, y, pa;
1599 /* now zero the buff */
1601 memset(c, 0, sizeof(c));
1603 /* copy the input */
1605 for (x = 0; x < oldused; x++) {
1611 /* now let's get bizz-sy! */
1612 for (x = 0; x < pa; x++) {
1613 /* get Mu for this round */
1616 /* our friendly neighbourhood alias */
1620 for (y = 0; y < pa; y++) {
1624 /* send carry up man... */
1629 /* fix the rest of the carries */
1631 for (x = pa; x < pa * 2 + 2; x++) {
1639 for (x = 0; x < pa+1; x++) {
1643 for (; x < oldused; x++) {
1652 /* if A >= m then A = A - m */
1653 if (fp_cmp_mag (a, m) != FP_LT) {
1658 /* End: fp_montgomery_reduce.c */
1660 /* Start: fp_montgomery_setup.c */
1661 /* TomsFastMath, a fast ISO C bignum library.
1663 * This project is meant to fill in where LibTomMath
1664 * falls short. That is speed ;-)
1666 * This project is public domain and free for all purposes.
1668 * Tom St Denis, tomstdenis@iahu.ca
1672 /* setups the montgomery reduction */
1673 int fp_montgomery_setup(fp_int *a, fp_digit *rho)
1677 /* fast inversion mod 2**k
1679 * Based on the fact that
1681 * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
1682 * => 2*X*A - X*X*A*A = 1
1683 * => 2*(1) - (1) = 1
1691 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
1692 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
1693 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
1694 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
1696 x *= 2 - b * x; /* here x*a==1 mod 2**64 */
1699 /* rho = -1/m mod b */
1700 *rho = (((fp_word) 1 << ((fp_word) DIGIT_BIT)) - ((fp_word)x));
1706 /* End: fp_montgomery_setup.c */
1708 /* Start: fp_mul.c */
1709 /* TomsFastMath, a fast ISO C bignum library.
1711 * This project is meant to fill in where LibTomMath
1712 * falls short. That is speed ;-)
1714 * This project is public domain and free for all purposes.
1716 * Tom St Denis, tomstdenis@iahu.ca
1721 void fp_mul(fp_int *A, fp_int *B, fp_int *C)
1724 fp_int ac, bd, comp, amb, cmd, t1, t2;
1726 y = MAX(A->used, B->used);
1727 yy = MIN(A->used, B->used);
1728 if (yy <= 8 || y <= 64) {
1730 /* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size
1731 of the largest input. We also want to avoid doing excess mults if the
1732 inputs are not close to the next power of two. That is, for example,
1733 if say y=17 then we would do (32-17)^2 = 225 unneeded multiplications
1736 fp_mul_comba4(A,B,C);
1737 } else if (y <= 8) {
1738 fp_mul_comba8(A,B,C);
1739 #if defined(TFM_LARGE)
1740 } else if (y <= 16 && y >= 10) {
1741 fp_mul_comba16(A,B,C);
1743 #if defined(TFM_HUGE)
1744 } else if (y <= 32 && y >= 24) {
1745 fp_mul_comba32(A,B,C);
1748 fp_mul_comba(A,B,C);
1751 /* do the karatsuba action
1753 if A = ab and B = cd for ||a|| = r we need to solve
1755 ac*r^2 + (-(a-b)(c-d) + ac + bd)*r + bd
1757 So we solve for the three products then we form the final result with careful shifting
1760 Obvious points of optimization
1762 - "ac" parts can be memcpy'ed with an offset [all you have to do is zero upto the next 8 digits]
1763 - Similarly the "bd" parts can be memcpy'ed and zeroed to 8
1767 /* get our value of r */
1770 /* now solve for ac */
1771 // fp_copy(A, &t1); fp_rshd(&t1, r);
1772 for (s = 0; s < A->used - r; s++) {
1773 t1.dp[s] = A->dp[s+r];
1775 for (; s < FP_SIZE; s++) {
1779 t1.used = A->used - r;
1785 // fp_copy(B, &t2); fp_rshd(&t2, r);
1786 for (s = 0; s < B->used - r; s++) {
1787 t2.dp[s] = B->dp[s+r];
1789 for (; s < FP_SIZE; s++) {
1793 t2.used = B->used - r;
1799 fp_copy(&t1, &amb); fp_copy(&t2, &cmd);
1801 fp_mul(&t1, &t2, &ac);
1803 /* now solve for bd */
1804 // fp_mod_2d(A, r * DIGIT_BIT, &t1);
1805 // fp_mod_2d(B, r * DIGIT_BIT, &t2);
1806 for (s = 0; s < r; s++) {
1807 t1.dp[s] = A->dp[s];
1808 t2.dp[s] = B->dp[s];
1810 for (; s < FP_SIZE; s++) {
1819 fp_sub(&amb, &t1, &amb); fp_sub(&cmd, &t2, &cmd);
1821 fp_mul(&t1, &t2, &bd);
1823 /* now get the (a-b)(c-d) term */
1825 fp_mul(&amb, &cmd, &comp);
1827 /* now solve the system, do the middle term first */
1829 fp_add(&comp, &ac, &comp);
1830 fp_add(&comp, &bd, &comp);
1836 /* now sum them together */
1837 s = A->sign ^ B->sign;
1839 fp_add(&ac, &comp, C);
1841 C->sign = C->used ? s : FP_ZPOS;
1848 /* Start: fp_mul_2.c */
1849 /* TomsFastMath, a fast ISO C bignum library.
1851 * This project is meant to fill in where LibTomMath
1852 * falls short. That is speed ;-)
1854 * This project is public domain and free for all purposes.
1856 * Tom St Denis, tomstdenis@iahu.ca
1860 void fp_mul_2(fp_int * a, fp_int * b)
1868 register fp_digit r, rr, *tmpa, *tmpb;
1870 /* alias for source */
1873 /* alias for dest */
1878 for (x = 0; x < a->used; x++) {
1880 /* get what will be the *next* carry bit from the
1881 * MSB of the current digit
1883 rr = *tmpa >> ((fp_digit)(DIGIT_BIT - 1));
1885 /* now shift up this digit, add in the carry [from the previous] */
1886 *tmpb++ = ((*tmpa++ << ((fp_digit)1)) | r);
1888 /* copy the carry that would be from the source
1889 * digit into the next iteration
1894 /* new leading digit? */
1895 if (r != 0 && b->used != (FP_SIZE-1)) {
1896 /* add a MSB which is always 1 at this point */
1901 /* now zero any excess digits on the destination
1902 * that we didn't write to
1904 tmpb = b->dp + b->used;
1905 for (x = b->used; x < oldused; x++) {
1913 /* End: fp_mul_2.c */
1915 /* Start: fp_mul_2d.c */
1916 /* TomsFastMath, a fast ISO C bignum library.
1918 * This project is meant to fill in where LibTomMath
1919 * falls short. That is speed ;-)
1921 * This project is public domain and free for all purposes.
1923 * Tom St Denis, tomstdenis@iahu.ca
1928 void fp_mul_2d(fp_int *a, int b, fp_int *c)
1930 fp_digit carry, carrytmp, shift;
1936 /* handle whole digits */
1937 if (b >= DIGIT_BIT) {
1938 fp_lshd(c, b/DIGIT_BIT);
1942 /* shift the digits */
1945 shift = DIGIT_BIT - b;
1946 for (x = 0; x < c->used; x++) {
1947 carrytmp = c->dp[x] >> shift;
1948 c->dp[x] = (c->dp[x] << b) + carry;
1951 /* store last carry if room */
1952 if (carry && x < FP_SIZE) {
1953 c->dp[c->used++] = carry;
1960 /* End: fp_mul_2d.c */
1962 /* Start: fp_mul_comba.c */
1963 /* TomsFastMath, a fast ISO C bignum library.
1965 * This project is meant to fill in where LibTomMath
1966 * falls short. That is speed ;-)
1968 * This project is public domain and free for all purposes.
1970 * Tom St Denis, tomstdenis@iahu.ca
1973 /* About this file...
1979 /* these are the combas. Worship them. */
1980 #if defined(TFM_X86)
1981 /* Generic x86 optimized code */
1983 /* anything you need at the start */
1986 /* clear the chaining variables */
1987 #define COMBA_CLEAR \
1990 /* forward the carry to the next digit */
1991 #define COMBA_FORWARD \
1992 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
1994 /* store the first sum */
1995 #define COMBA_STORE(x) \
1998 /* store the second sum [carry] */
1999 #define COMBA_STORE2(x) \
2002 /* anything you need at the end */
2005 /* this should multiply i and j */
2006 #define MULADD(i, j) \
2008 "movl %6,%%eax \n\t" \
2010 "addl %%eax,%0 \n\t" \
2011 "adcl %%edx,%1 \n\t" \
2013 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc");
2015 #elif defined(TFM_X86_64)
2016 /* x86-64 optimized */
2018 /* anything you need at the start */
2021 /* clear the chaining variables */
2022 #define COMBA_CLEAR \
2025 /* forward the carry to the next digit */
2026 #define COMBA_FORWARD \
2027 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
2029 /* store the first sum */
2030 #define COMBA_STORE(x) \
2033 /* store the second sum [carry] */
2034 #define COMBA_STORE2(x) \
2037 /* anything you need at the end */
2040 /* this should multiply i and j */
2041 #define MULADD(i, j) \
2043 "movq %6,%%rax \n\t" \
2045 "addq %%rax,%0 \n\t" \
2046 "adcq %%rdx,%1 \n\t" \
2048 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
2050 #elif defined(TFM_SSE2)
2051 /* use SSE2 optimizations */
2053 /* anything you need at the start */
2056 /* clear the chaining variables */
2057 #define COMBA_CLEAR \
2060 /* forward the carry to the next digit */
2061 #define COMBA_FORWARD \
2062 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
2064 /* store the first sum */
2065 #define COMBA_STORE(x) \
2068 /* store the second sum [carry] */
2069 #define COMBA_STORE2(x) \
2072 /* anything you need at the end */
2073 #define COMBA_FINI \
2076 /* this should multiply i and j */
2077 #define MULADD(i, j) \
2079 "movd %6,%%mm0 \n\t" \
2080 "movd %7,%%mm1 \n\t" \
2081 "pmuludq %%mm1,%%mm0\n\t" \
2082 "movd %%mm0,%%eax \n\t" \
2083 "psrlq $32,%%mm0 \n\t" \
2084 "addl %%eax,%0 \n\t" \
2085 "movd %%mm0,%%eax \n\t" \
2086 "adcl %%eax,%1 \n\t" \
2088 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%cc");
2090 #elif defined(TFM_ARM)
2095 #define COMBA_CLEAR \
2098 #define COMBA_FORWARD \
2099 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
2101 #define COMBA_STORE(x) \
2104 #define COMBA_STORE2(x) \
2109 #define MULADD(i, j) \
2111 " UMULL r0,r1,%6,%7 \n\t" \
2112 " ADDS %0,%0,r0 \n\t" \
2113 " ADCS %1,%1,r1 \n\t" \
2114 " ADC %2, %2, #0 \n\t" \
2115 :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc");
2122 #define COMBA_CLEAR \
2125 #define COMBA_FORWARD \
2126 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
2128 #define COMBA_STORE(x) \
2131 #define COMBA_STORE2(x) \
2136 #define MULADD(i, j) \
2138 t = (fp_word)c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \
2139 t = (fp_word)c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \
2145 /* generic PxQ multiplier */
2146 void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C)
2148 int ix, iy, iz, tx, ty, pa;
2149 fp_digit c0, c1, c2, *tmpx, *tmpy;
2155 /* get size of output and trim */
2156 pa = A->used + B->used;
2157 if (pa >= FP_SIZE) {
2161 if (A == C || B == C) {
2169 for (ix = 0; ix < pa; ix++) {
2170 /* get offsets into the two bignums */
2171 ty = MIN(ix, B->used-1);
2174 /* setup temp aliases */
2178 /* this is the number of times the loop will iterrate, essentially its
2179 while (tx++ < a->used && ty-- >= 0) { ... }
2181 iy = MIN(A->used-tx, ty+1);
2185 for (iz = 0; iz < iy; ++iz) {
2186 MULADD(*tmpx++, *tmpy--);
2190 COMBA_STORE(dst->dp[ix]);
2192 /* store final carry */
2193 COMBA_STORE2(dst->dp[ix]);
2198 dst->sign = dst->used ? A->sign ^ B->sign : FP_ZPOS;
2202 void fp_mul_comba4(fp_int *A, fp_int *B, fp_int *C)
2204 fp_digit c0, c1, c2, at[8];
2206 memcpy(at, A->dp, 4 * sizeof(fp_digit));
2207 memcpy(at+4, B->dp, 4 * sizeof(fp_digit));
2212 MULADD(at[0], at[4]);
2213 COMBA_STORE(C->dp[0]);
2216 MULADD(at[0], at[5]); MULADD(at[1], at[4]);
2217 COMBA_STORE(C->dp[1]);
2220 MULADD(at[0], at[6]); MULADD(at[1], at[5]); MULADD(at[2], at[4]);
2221 COMBA_STORE(C->dp[2]);
2224 MULADD(at[0], at[7]); MULADD(at[1], at[6]); MULADD(at[2], at[5]); MULADD(at[3], at[4]);
2225 COMBA_STORE(C->dp[3]);
2228 MULADD(at[1], at[7]); MULADD(at[2], at[6]); MULADD(at[3], at[5]);
2229 COMBA_STORE(C->dp[4]);
2232 MULADD(at[2], at[7]); MULADD(at[3], at[6]);
2233 COMBA_STORE(C->dp[5]);
2236 MULADD(at[3], at[7]);
2237 COMBA_STORE(C->dp[6]);
2238 COMBA_STORE2(C->dp[7]);
2240 C->sign = A->sign ^ B->sign;
2246 void fp_mul_comba8(fp_int *A, fp_int *B, fp_int *C)
2248 fp_digit c0, c1, c2, at[16];
2250 memcpy(at, A->dp, 8 * sizeof(fp_digit));
2251 memcpy(at+8, B->dp, 8 * sizeof(fp_digit));
2256 MULADD(at[0], at[8]);
2257 COMBA_STORE(C->dp[0]);
2260 MULADD(at[0], at[9]); MULADD(at[1], at[8]);
2261 COMBA_STORE(C->dp[1]);
2264 MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]);
2265 COMBA_STORE(C->dp[2]);
2268 MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]);
2269 COMBA_STORE(C->dp[3]);
2272 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]);
2273 COMBA_STORE(C->dp[4]);
2276 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]);
2277 COMBA_STORE(C->dp[5]);
2280 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]);
2281 COMBA_STORE(C->dp[6]);
2284 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]);
2285 COMBA_STORE(C->dp[7]);
2288 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]);
2289 COMBA_STORE(C->dp[8]);
2292 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]);
2293 COMBA_STORE(C->dp[9]);
2296 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]);
2297 COMBA_STORE(C->dp[10]);
2300 MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]);
2301 COMBA_STORE(C->dp[11]);
2304 MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]);
2305 COMBA_STORE(C->dp[12]);
2308 MULADD(at[6], at[15]); MULADD(at[7], at[14]);
2309 COMBA_STORE(C->dp[13]);
2312 MULADD(at[7], at[15]);
2313 COMBA_STORE(C->dp[14]);
2314 COMBA_STORE2(C->dp[15]);
2316 C->sign = A->sign ^ B->sign;
2321 #if defined(TFM_LARGE)
2323 void fp_mul_comba16(fp_int *A, fp_int *B, fp_int *C)
2325 fp_digit c0, c1, c2, at[32];
2327 memcpy(at, A->dp, 16 * sizeof(fp_digit));
2328 memcpy(at+16, B->dp, 16 * sizeof(fp_digit));
2333 MULADD(at[0], at[16]);
2334 COMBA_STORE(C->dp[0]);
2337 MULADD(at[0], at[17]); MULADD(at[1], at[16]);
2338 COMBA_STORE(C->dp[1]);
2341 MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]);
2342 COMBA_STORE(C->dp[2]);
2345 MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]);
2346 COMBA_STORE(C->dp[3]);
2349 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]);
2350 COMBA_STORE(C->dp[4]);
2353 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]);
2354 COMBA_STORE(C->dp[5]);
2357 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]);
2358 COMBA_STORE(C->dp[6]);
2361 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]);
2362 COMBA_STORE(C->dp[7]);
2365 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]);
2366 COMBA_STORE(C->dp[8]);
2369 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]);
2370 COMBA_STORE(C->dp[9]);
2373 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]);
2374 COMBA_STORE(C->dp[10]);
2377 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]);
2378 COMBA_STORE(C->dp[11]);
2381 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]);
2382 COMBA_STORE(C->dp[12]);
2385 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]);
2386 COMBA_STORE(C->dp[13]);
2389 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]);
2390 COMBA_STORE(C->dp[14]);
2393 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]);
2394 COMBA_STORE(C->dp[15]);
2397 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]);
2398 COMBA_STORE(C->dp[16]);
2401 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]);
2402 COMBA_STORE(C->dp[17]);
2405 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]);
2406 COMBA_STORE(C->dp[18]);
2409 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]);
2410 COMBA_STORE(C->dp[19]);
2413 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]);
2414 COMBA_STORE(C->dp[20]);
2417 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]);
2418 COMBA_STORE(C->dp[21]);
2421 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]);
2422 COMBA_STORE(C->dp[22]);
2425 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]);
2426 COMBA_STORE(C->dp[23]);
2429 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]);
2430 COMBA_STORE(C->dp[24]);
2433 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]);
2434 COMBA_STORE(C->dp[25]);
2437 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]);
2438 COMBA_STORE(C->dp[26]);
2441 MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]);
2442 COMBA_STORE(C->dp[27]);
2445 MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]);
2446 COMBA_STORE(C->dp[28]);
2449 MULADD(at[14], at[31]); MULADD(at[15], at[30]);
2450 COMBA_STORE(C->dp[29]);
2453 MULADD(at[15], at[31]);
2454 COMBA_STORE(C->dp[30]);
2455 COMBA_STORE2(C->dp[31]);
2457 C->sign = A->sign ^ B->sign;
2462 #endif /* TFM_LARGE */
2466 void fp_mul_comba32(fp_int *A, fp_int *B, fp_int *C)
2468 fp_digit c0, c1, c2, at[64];
2470 memcpy(at, A->dp, 32 * sizeof(fp_digit));
2471 memcpy(at+32, B->dp, 32 * sizeof(fp_digit));
2476 MULADD(at[0], at[32]);
2477 COMBA_STORE(C->dp[0]);
2480 MULADD(at[0], at[33]); MULADD(at[1], at[32]);
2481 COMBA_STORE(C->dp[1]);
2484 MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]);
2485 COMBA_STORE(C->dp[2]);
2488 MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]);
2489 COMBA_STORE(C->dp[3]);
2492 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]);
2493 COMBA_STORE(C->dp[4]);
2496 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]);
2497 COMBA_STORE(C->dp[5]);
2500 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]);
2501 COMBA_STORE(C->dp[6]);
2504 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]);
2505 COMBA_STORE(C->dp[7]);
2508 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]);
2509 COMBA_STORE(C->dp[8]);
2512 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]);
2513 COMBA_STORE(C->dp[9]);
2516 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]);
2517 COMBA_STORE(C->dp[10]);
2520 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]);
2521 COMBA_STORE(C->dp[11]);
2524 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]);
2525 COMBA_STORE(C->dp[12]);
2528 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]);
2529 COMBA_STORE(C->dp[13]);
2532 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]);
2533 COMBA_STORE(C->dp[14]);
2536 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]);
2537 COMBA_STORE(C->dp[15]);
2540 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]);
2541 COMBA_STORE(C->dp[16]);
2544 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]);
2545 COMBA_STORE(C->dp[17]);
2548 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]);
2549 COMBA_STORE(C->dp[18]);
2552 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]);
2553 COMBA_STORE(C->dp[19]);
2556 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]);
2557 COMBA_STORE(C->dp[20]);
2560 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]);
2561 COMBA_STORE(C->dp[21]);
2564 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]);
2565 COMBA_STORE(C->dp[22]);
2568 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]);
2569 COMBA_STORE(C->dp[23]);
2572 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]);
2573 COMBA_STORE(C->dp[24]);
2576 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]);
2577 COMBA_STORE(C->dp[25]);
2580 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]);
2581 COMBA_STORE(C->dp[26]);
2584 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]);
2585 COMBA_STORE(C->dp[27]);
2588 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]);
2589 COMBA_STORE(C->dp[28]);
2592 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]);
2593 COMBA_STORE(C->dp[29]);
2596 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]);
2597 COMBA_STORE(C->dp[30]);
2600 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]);
2601 COMBA_STORE(C->dp[31]);
2604 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]);
2605 COMBA_STORE(C->dp[32]);
2608 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]);
2609 COMBA_STORE(C->dp[33]);
2612 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]);
2613 COMBA_STORE(C->dp[34]);
2616 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]);
2617 COMBA_STORE(C->dp[35]);
2620 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]);
2621 COMBA_STORE(C->dp[36]);
2624 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]);
2625 COMBA_STORE(C->dp[37]);
2628 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]);
2629 COMBA_STORE(C->dp[38]);
2632 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]);
2633 COMBA_STORE(C->dp[39]);
2636 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]);
2637 COMBA_STORE(C->dp[40]);
2640 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]);
2641 COMBA_STORE(C->dp[41]);
2644 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]);
2645 COMBA_STORE(C->dp[42]);
2648 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]);
2649 COMBA_STORE(C->dp[43]);
2652 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]);
2653 COMBA_STORE(C->dp[44]);
2656 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]);
2657 COMBA_STORE(C->dp[45]);
2660 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]);
2661 COMBA_STORE(C->dp[46]);
2664 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]);
2665 COMBA_STORE(C->dp[47]);
2668 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]);
2669 COMBA_STORE(C->dp[48]);
2672 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]);
2673 COMBA_STORE(C->dp[49]);
2676 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]);
2677 COMBA_STORE(C->dp[50]);
2680 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]);
2681 COMBA_STORE(C->dp[51]);
2684 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]);
2685 COMBA_STORE(C->dp[52]);
2688 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]);
2689 COMBA_STORE(C->dp[53]);
2692 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]);
2693 COMBA_STORE(C->dp[54]);
2696 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]);
2697 COMBA_STORE(C->dp[55]);
2700 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]);
2701 COMBA_STORE(C->dp[56]);
2704 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]);
2705 COMBA_STORE(C->dp[57]);
2708 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]);
2709 COMBA_STORE(C->dp[58]);
2712 MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]);
2713 COMBA_STORE(C->dp[59]);
2716 MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]);
2717 COMBA_STORE(C->dp[60]);
2720 MULADD(at[30], at[63]); MULADD(at[31], at[62]);
2721 COMBA_STORE(C->dp[61]);
2724 MULADD(at[31], at[63]);
2725 COMBA_STORE(C->dp[62]);
2726 COMBA_STORE2(C->dp[63]);
2728 C->sign = A->sign ^ B->sign;
2735 /* End: fp_mul_comba.c */
2737 /* Start: fp_mul_d.c */
2738 /* TomsFastMath, a fast ISO C bignum library.
2740 * This project is meant to fill in where LibTomMath
2741 * falls short. That is speed ;-)
2743 * This project is public domain and free for all purposes.
2745 * Tom St Denis, tomstdenis@iahu.ca
2750 void fp_mul_d(fp_int *a, fp_digit b, fp_int *c)
2759 for (x = 0; x < a->used; x++) {
2760 w = ((fp_word)a->dp[x]) * ((fp_word)b) + w;
2761 c->dp[x] = (fp_digit)w;
2764 if (w != 0 && (a->used != FP_SIZE)) {
2765 c->dp[c->used++] = w;
2768 for (; x < oldused; x++) {
2775 /* End: fp_mul_d.c */
2777 /* Start: fp_mulmod.c */
2778 /* TomsFastMath, a fast ISO C bignum library.
2780 * This project is meant to fill in where LibTomMath
2781 * falls short. That is speed ;-)
2783 * This project is public domain and free for all purposes.
2785 * Tom St Denis, tomstdenis@iahu.ca
2788 /* d = a * b (mod c) */
2789 int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
2794 return fp_mod(&tmp, c, d);
2797 /* End: fp_mulmod.c */
2799 /* Start: fp_prime_miller_rabin.c */
2800 /* TomsFastMath, a fast ISO C bignum library.
2802 * This project is meant to fill in where LibTomMath
2803 * falls short. That is speed ;-)
2805 * This project is public domain and free for all purposes.
2807 * Tom St Denis, tomstdenis@iahu.ca
2811 /* Miller-Rabin test of "a" to the base of "b" as described in
2812 * HAC pp. 139 Algorithm 4.24
2814 * Sets result to 0 if definitely composite or 1 if probably prime.
2815 * Randomly the chance of error is no more than 1/4 and often
2818 void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
2827 if (fp_cmp_d(b, 1) != FP_GT) {
2831 /* get n1 = a - 1 */
2832 fp_init_copy(&n1, a);
2833 fp_sub_d(&n1, 1, &n1);
2835 /* set 2**s * r = n1 */
2836 fp_init_copy(&r, &n1);
2838 /* count the number of least significant bits
2843 /* now divide n - 1 by 2**s */
2844 fp_div_2d (&r, s, &r, NULL);
2846 /* compute y = b**r mod a */
2848 fp_exptmod(b, &r, a, &y);
2850 /* if y != 1 and y != n1 do */
2851 if (fp_cmp_d (&y, 1) != FP_EQ && fp_cmp (&y, &n1) != FP_EQ) {
2853 /* while j <= s-1 and y != n1 */
2854 while ((j <= (s - 1)) && fp_cmp (&y, &n1) != FP_EQ) {
2855 fp_sqrmod (&y, a, &y);
2857 /* if y == 1 then composite */
2858 if (fp_cmp_d (&y, 1) == FP_EQ) {
2864 /* if y != n1 then composite */
2865 if (fp_cmp (&y, &n1) != FP_EQ) {
2870 /* probably prime now */
2874 /* End: fp_prime_miller_rabin.c */
2876 /* Start: fp_prime_random_ex.c */
2877 /* TomsFastMath, a fast ISO C bignum library.
2879 * This project is meant to fill in where LibTomMath
2880 * falls short. That is speed ;-)
2882 * This project is public domain and free for all purposes.
2884 * Tom St Denis, tomstdenis@iahu.ca
2888 /* This is possibly the mother of all prime generation functions, muahahahahaha! */
2889 int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat)
2891 unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
2892 int res, err, bsize, maskOR_msb_offset;
2894 /* sanity check the input */
2895 if (size <= 1 || t <= 0) {
2899 /* TFM_PRIME_SAFE implies TFM_PRIME_BBS */
2900 if (flags & TFM_PRIME_SAFE) {
2901 flags |= TFM_PRIME_BBS;
2904 /* calc the byte size */
2905 bsize = (size>>3)+(size&7?1:0);
2907 /* we need a buffer of bsize bytes */
2908 tmp = malloc(bsize);
2913 /* calc the maskAND value for the MSbyte*/
2914 maskAND = 0xFF >> (8 - (size & 7));
2916 /* calc the maskOR_msb */
2918 maskOR_msb_offset = (size - 2) >> 3;
2919 if (flags & TFM_PRIME_2MSB_ON) {
2920 maskOR_msb |= 1 << ((size - 2) & 7);
2921 } else if (flags & TFM_PRIME_2MSB_OFF) {
2922 maskAND &= ~(1 << ((size - 2) & 7));
2925 /* get the maskOR_lsb */
2927 if (flags & TFM_PRIME_BBS) {
2932 /* read the bytes */
2933 if (cb(tmp, bsize, dat) != bsize) {
2938 /* work over the MSbyte */
2940 tmp[0] |= 1 << ((size - 1) & 7);
2942 /* mix in the maskORs */
2943 tmp[maskOR_msb_offset] |= maskOR_msb;
2944 tmp[bsize-1] |= maskOR_lsb;
2947 fp_read_unsigned_bin(a, tmp, bsize);
2950 res = fp_isprime(a);
2951 if (res == FP_NO) continue;
2953 if (flags & TFM_PRIME_SAFE) {
2954 /* see if (a-1)/2 is prime */
2959 res = fp_isprime(a);
2961 } while (res == FP_NO);
2963 if (flags & TFM_PRIME_SAFE) {
2964 /* restore a to the original value */
2975 /* End: fp_prime_random_ex.c */
2977 /* Start: fp_radix_size.c */
2978 /* TomsFastMath, a fast ISO C bignum library.
2980 * This project is meant to fill in where LibTomMath
2981 * falls short. That is speed ;-)
2983 * This project is public domain and free for all purposes.
2985 * Tom St Denis, tomstdenis@iahu.ca
2989 int fp_radix_size(fp_int *a, int radix, int *size)
2997 /* check range of the radix */
2998 if (radix < 2 || radix > 64) {
3002 /* quick out if its zero */
3003 if (fp_iszero(a) == 1) {
3008 fp_init_copy(&t, a);
3010 /* if it is negative output a - */
3011 if (t.sign == FP_NEG) {
3017 while (fp_iszero (&t) == FP_NO) {
3018 fp_div_d (&t, (fp_digit) radix, &t, &d);
3022 /* append a NULL so the string is properly terminated */
3028 /* End: fp_radix_size.c */
3030 /* Start: fp_read_radix.c */
3031 /* TomsFastMath, a fast ISO C bignum library.
3033 * This project is meant to fill in where LibTomMath
3034 * falls short. That is speed ;-)
3036 * This project is public domain and free for all purposes.
3038 * Tom St Denis, tomstdenis@iahu.ca
3042 int fp_read_radix(fp_int *a, char *str, int radix)
3047 /* make sure the radix is ok */
3048 if (radix < 2 || radix > 64) {
3052 /* if the leading digit is a
3053 * minus set the sign to negative.
3062 /* set the integer to the default of zero */
3065 /* process each digit of the string */
3067 /* if the radix < 36 the conversion is case insensitive
3068 * this allows numbers like 1AB and 1ab to represent the same value
3071 ch = (char) ((radix < 36) ? toupper (*str) : *str);
3072 for (y = 0; y < 64; y++) {
3073 if (ch == fp_s_rmap[y]) {
3078 /* if the char was found in the map
3079 * and is less than the given radix add it
3080 * to the number, otherwise exit the loop.
3083 fp_mul_d (a, (fp_digit) radix, a);
3084 fp_add_d (a, (fp_digit) y, a);
3091 /* set the sign only if a != 0 */
3092 if (fp_iszero(a) != FP_YES) {
3098 /* End: fp_read_radix.c */
3100 /* Start: fp_read_signed_bin.c */
3101 /* TomsFastMath, a fast ISO C bignum library.
3103 * This project is meant to fill in where LibTomMath
3104 * falls short. That is speed ;-)
3106 * This project is public domain and free for all purposes.
3108 * Tom St Denis, tomstdenis@iahu.ca
3112 void fp_read_signed_bin(fp_int *a, unsigned char *b, int c)
3114 /* read magnitude */
3115 fp_read_unsigned_bin (a, b + 1, c - 1);
3117 /* first byte is 0 for positive, non-zero for negative */
3125 /* End: fp_read_signed_bin.c */
3127 /* Start: fp_read_unsigned_bin.c */
3128 /* TomsFastMath, a fast ISO C bignum library.
3130 * This project is meant to fill in where LibTomMath
3131 * falls short. That is speed ;-)
3133 * This project is public domain and free for all purposes.
3135 * Tom St Denis, tomstdenis@iahu.ca
3139 void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c)
3144 /* read the bytes in */
3145 for (; c > 0; c--) {
3146 fp_mul_2d (a, 8, a);
3153 /* End: fp_read_unsigned_bin.c */
3155 /* Start: fp_reverse.c */
3156 /* TomsFastMath, a fast ISO C bignum library.
3158 * This project is meant to fill in where LibTomMath
3159 * falls short. That is speed ;-)
3161 * This project is public domain and free for all purposes.
3163 * Tom St Denis, tomstdenis@iahu.ca
3167 /* reverse an array, used for radix code */
3168 void bn_reverse (unsigned char *s, int len)
3184 /* End: fp_reverse.c */
3186 /* Start: fp_rshd.c */
3187 /* TomsFastMath, a fast ISO C bignum library.
3189 * This project is meant to fill in where LibTomMath
3190 * falls short. That is speed ;-)
3192 * This project is public domain and free for all purposes.
3194 * Tom St Denis, tomstdenis@iahu.ca
3198 void fp_rshd(fp_int *a, int x)
3202 /* too many digits just zero and return */
3209 for (y = 0; y < a->used - x; y++) {
3210 a->dp[y] = a->dp[y+x];
3214 for (; y < a->used; y++) {
3218 /* decrement count */
3224 /* End: fp_rshd.c */
3226 /* Start: fp_s_rmap.c */
3227 /* TomsFastMath, a fast ISO C bignum library.
3229 * This project is meant to fill in where LibTomMath
3230 * falls short. That is speed ;-)
3232 * This project is public domain and free for all purposes.
3234 * Tom St Denis, tomstdenis@iahu.ca
3238 /* chars used in radix conversions */
3239 const char *fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
3241 /* End: fp_s_rmap.c */
3243 /* Start: fp_set.c */
3244 /* TomsFastMath, a fast ISO C bignum library.
3246 * This project is meant to fill in where LibTomMath
3247 * falls short. That is speed ;-)
3249 * This project is public domain and free for all purposes.
3251 * Tom St Denis, tomstdenis@iahu.ca
3255 void fp_set(fp_int *a, fp_digit b)
3259 a->used = b ? 1 : 0;
3264 /* Start: fp_signed_bin_size.c */
3265 /* TomsFastMath, a fast ISO C bignum library.
3267 * This project is meant to fill in where LibTomMath
3268 * falls short. That is speed ;-)
3270 * This project is public domain and free for all purposes.
3272 * Tom St Denis, tomstdenis@iahu.ca
3276 int fp_signed_bin_size(fp_int *a)
3278 return 1 + fp_unsigned_bin_size (a);
3281 /* End: fp_signed_bin_size.c */
3283 /* Start: fp_sqr.c */
3284 /* TomsFastMath, a fast ISO C bignum library.
3286 * This project is meant to fill in where LibTomMath
3287 * falls short. That is speed ;-)
3289 * This project is public domain and free for all purposes.
3291 * Tom St Denis, tomstdenis@iahu.ca
3296 void fp_sqr(fp_int *A, fp_int *B)
3299 fp_int aa, bb, comp, amb, t1;
3305 } else if (y <= 8) {
3307 #if defined(TFM_LARGE)
3308 } else if (y <= 16 && y >= 12) {
3309 fp_sqr_comba16(A,B);
3311 #if defined(TFM_HUGE)
3312 } else if (y <= 32 && y >= 20) {
3313 fp_sqr_comba32(A,B);
3314 } else if (y <= 64 && y >= 48) {
3315 fp_sqr_comba64(A,B);
3322 /* do the karatsuba action
3324 if A = ab ||a|| = r we need to solve
3326 a^2*r^2 + (-(a-b)^2 + a^2 + b^2)*r + b^2
3328 So we solve for the three products then we form the final result with careful shifting
3331 Obvious points of optimization
3333 - "ac" parts can be memcpy'ed with an offset [all you have to do is zero upto the next 8 digits]
3334 - Similarly the "bd" parts can be memcpy'ed and zeroed to 8
3338 /* get our value of r */
3341 /* now solve for ac */
3342 // fp_copy(A, &t1); fp_rshd(&t1, r);
3343 for (s = 0; s < A->used - r; s++) {
3344 t1.dp[s] = A->dp[s+r];
3346 for (; s < FP_SIZE; s++) {
3350 t1.used = A->used - r;
3359 /* now solve for bd */
3360 // fp_mod_2d(A, r * DIGIT_BIT, &t1);
3361 for (s = 0; s < r; s++) {
3362 t1.dp[s] = A->dp[s];
3364 for (; s < FP_SIZE; s++) {
3370 fp_sub(&amb, &t1, &amb);
3374 /* now get the (a-b) term */
3376 fp_sqr(&amb, &comp);
3378 /* now solve the system, do the middle term first */
3380 fp_add(&comp, &aa, &comp);
3381 fp_add(&comp, &bb, &comp);
3387 /* now sum them together */
3389 fp_add(&aa, &comp, B);
3398 /* Start: fp_sqr_comba.c */
3399 /* TomsFastMath, a fast ISO C bignum library.
3401 * This project is meant to fill in where LibTomMath
3402 * falls short. That is speed ;-)
3404 * This project is public domain and free for all purposes.
3406 * Tom St Denis, tomstdenis@iahu.ca
3410 /* About this file...
3413 #if defined(TFM_X86)
3415 /* x86-32 optimized */
3419 #define CLEAR_CARRY \
3422 #define COMBA_STORE(x) \
3425 #define COMBA_STORE2(x) \
3428 #define CARRY_FORWARD \
3429 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
3433 #define SQRADD(i, j) \
3435 "movl %6,%%eax \n\t" \
3437 "addl %%eax,%0 \n\t" \
3438 "adcl %%edx,%1 \n\t" \
3440 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc");
3442 #define SQRADD2(i, j) \
3444 "movl %6,%%eax \n\t" \
3446 "addl %%eax,%0 \n\t" \
3447 "adcl %%edx,%1 \n\t" \
3449 "addl %%eax,%0 \n\t" \
3450 "adcl %%edx,%1 \n\t" \
3452 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc");
3454 #define SQRADDSC(i, j) \
3456 "movl %6,%%eax \n\t" \
3458 "movl %%eax,%0 \n\t" \
3459 "movl %%edx,%1 \n\t" \
3461 :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","%cc");
3463 #define SQRADDAC(i, j) \
3465 "movl %6,%%eax \n\t" \
3467 "addl %%eax,%0 \n\t" \
3468 "adcl %%edx,%1 \n\t" \
3470 :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","%cc");
3480 :"=r"(c0), "=r"(c1), "=r"(c2), "=g"(sc0), "=g"(sc1), "=g"(sc2) : "0"(c0), "1"(c1), "2"(c2), "3"(sc0), "4"(sc1), "5"(sc2) : "%cc");
3482 #elif defined(TFM_X86_64)
3483 /* x86-64 optimized */
3487 #define CLEAR_CARRY \
3490 #define COMBA_STORE(x) \
3493 #define COMBA_STORE2(x) \
3496 #define CARRY_FORWARD \
3497 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
3501 #define SQRADD(i, j) \
3503 "movq %6,%%rax \n\t" \
3505 "addq %%rax,%0 \n\t" \
3506 "adcq %%rdx,%1 \n\t" \
3508 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","%cc");
3510 #define SQRADD2(i, j) \
3512 "movq %6,%%rax \n\t" \
3514 "addq %%rax,%0 \n\t" \
3515 "adcq %%rdx,%1 \n\t" \
3517 "addq %%rax,%0 \n\t" \
3518 "adcq %%rdx,%1 \n\t" \
3520 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
3522 #define SQRADDSC(i, j) \
3524 "movq %6,%%rax \n\t" \
3526 "movq %%rax,%0 \n\t" \
3527 "movq %%rdx,%1 \n\t" \
3529 :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
3531 #define SQRADDAC(i, j) \
3533 "movq %6,%%rax \n\t" \
3535 "addq %%rax,%0 \n\t" \
3536 "adcq %%rdx,%1 \n\t" \
3538 :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
3548 :"=r"(c0), "=r"(c1), "=r"(c2), "=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(c0), "1"(c1), "2"(c2), "3"(sc0), "4"(sc1), "5"(sc2) : "%cc");
3550 #elif defined(TFM_SSE2)
3552 /* SSE2 Optimized */
3555 #define CLEAR_CARRY \
3558 #define COMBA_STORE(x) \
3561 #define COMBA_STORE2(x) \
3564 #define CARRY_FORWARD \
3565 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
3567 #define COMBA_FINI \
3570 #define SQRADD(i, j) \
3572 "movd %6,%%mm0 \n\t" \
3573 "pmuludq %%mm0,%%mm0\n\t" \
3574 "movd %%mm0,%%eax \n\t" \
3575 "psrlq $32,%%mm0 \n\t" \
3576 "addl %%eax,%0 \n\t" \
3577 "movd %%mm0,%%eax \n\t" \
3578 "adcl %%eax,%1 \n\t" \
3580 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%cc");
3582 #define SQRADD2(i, j) \
3584 "movd %6,%%mm0 \n\t" \
3585 "movd %7,%%mm1 \n\t" \
3586 "pmuludq %%mm1,%%mm0\n\t" \
3587 "movd %%mm0,%%eax \n\t" \
3588 "psrlq $32,%%mm0 \n\t" \
3589 "movd %%mm0,%%edx \n\t" \
3590 "addl %%eax,%0 \n\t" \
3591 "adcl %%edx,%1 \n\t" \
3593 "addl %%eax,%0 \n\t" \
3594 "adcl %%edx,%1 \n\t" \
3596 :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc");
3598 #define SQRADDSC(i, j) \
3600 "movd %6,%%mm0 \n\t" \
3601 "pmuludq %%mm0,%%mm0\n\t" \
3602 "movd %%mm0,%%eax \n\t" \
3603 "psrlq $32,%%mm0 \n\t" \
3604 "movl %%eax,%0 \n\t" \
3605 "movd %%mm0,%%eax \n\t" \
3606 "movl %%eax,%1 \n\t" \
3608 :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "m"(i) :"%eax","%cc");
3610 #define SQRADDAC(i, j) \
3612 "movd %6,%%mm0 \n\t" \
3613 "movd %7,%%mm1 \n\t" \
3614 "pmuludq %%mm1,%%mm0\n\t" \
3615 "movd %%mm0,%%eax \n\t" \
3616 "psrlq $32,%%mm0 \n\t" \
3617 "movd %%mm0,%%edx \n\t" \
3618 "addl %%eax,%0 \n\t" \
3619 "adcl %%edx,%1 \n\t" \
3621 "addl %%eax,%0 \n\t" \
3622 "adcl %%edx,%1 \n\t" \
3624 :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "m"(i), "m"(j) :"%eax","%edx","%cc");
3634 :"=r"(c0), "=r"(c1), "=r"(c2), "=g"(sc0), "=g"(sc1), "=g"(sc2) : "0"(c0), "1"(c1), "2"(c2), "3"(sc0), "4"(sc1), "5"(sc2) : "%cc");
3636 #elif defined(TFM_ARM)
3642 #define CLEAR_CARRY \
3645 #define COMBA_STORE(x) \
3648 #define COMBA_STORE2(x) \
3651 #define CARRY_FORWARD \
3652 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
3656 /* multiplies point i and j, updates carry "c1" and digit c2 */
3657 #define SQRADD(i, j) \
3659 " UMULL r0,r1,%6,%6 \n\t" \
3660 " ADDS %0,%0,r0 \n\t" \
3661 " ADCS %1,%1,r1 \n\t" \
3662 " ADC %2,%2,#0 \n\t" \
3663 :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i) : "r0", "r1", "%cc");
3665 /* for squaring some of the terms are doubled... */
3666 #define SQRADD2(i, j) \
3668 " UMULL r0,r1,%6,%7 \n\t" \
3669 " ADDS %0,%0,r0 \n\t" \
3670 " ADCS %1,%1,r1 \n\t" \
3671 " ADC %2,%2,#0 \n\t" \
3672 " ADDS %0,%0,r0 \n\t" \
3673 " ADCS %1,%1,r1 \n\t" \
3674 " ADC %2,%2,#0 \n\t" \
3675 :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc");
3677 #define SQRADDSC(i, j) \
3679 " UMULL %0,%1,%6,%7 \n\t" \
3680 " SUB %2,%2,%2 \n\t" \
3681 :"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "%cc");
3683 #define SQRADDAC(i, j) \
3685 " UMULL r0,r1,%6,%7 \n\t" \
3686 " ADDS %0,%0,r0 \n\t" \
3687 " ADCS %1,%1,r1 \n\t" \
3688 " ADC %2,%2,#0 \n\t" \
3689 :"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "r0", "r1", "%cc");
3693 " ADDS %3,%0 \n\t" \
3694 " ADCS %4,%1 \n\t" \
3696 " ADDS %3,%0 \n\t" \
3697 " ADCS %4,%1 \n\t" \
3699 :"=r"(sc0), "=r"(sc1), "=r"(sc2), "=r"(c0), "=r"(c1), "=r"(c2) : "0"(sc0), "1"(sc1), "2"(sc2), "3"(c0), "4"(c1), "5"(c2) : "%cc");
3703 /* ISO C portable code */
3705 #define COMBA_START \
3708 #define CLEAR_CARRY \
3711 #define COMBA_STORE(x) \
3714 #define COMBA_STORE2(x) \
3717 #define CARRY_FORWARD \
3718 do { c0 = c1; c1 = c2; c2 = 0; } while (0);
3720 #define COMBA_FINI \
3723 /* multiplies point i and j, updates carry "c1" and digit c2 */
3724 #define SQRADD(i, j) \
3726 t = c0 + ((fp_word)i) * ((fp_word)j); c0 = t; \
3727 t = c1 + (t >> DIGIT_BIT); c1 = t; c2 += t >> DIGIT_BIT; \
3731 /* for squaring some of the terms are doubled... */
3732 #define SQRADD2(i, j) \
3734 t = ((fp_word)i) * ((fp_word)j); \
3735 tt = (fp_word)c0 + t; c0 = tt; \
3736 tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \
3737 tt = (fp_word)c0 + t; c0 = tt; \
3738 tt = (fp_word)c1 + (tt >> DIGIT_BIT); c1 = tt; c2 += tt >> DIGIT_BIT; \
3741 #define SQRADDSC(i, j) \
3743 t = ((fp_word)i) * ((fp_word)j); \
3744 sc0 = (fp_digit)t; sc1 = (t >> DIGIT_BIT); sc2 = 0; \
3747 #define SQRADDAC(i, j) \
3749 t = sc0 + ((fp_word)i) * ((fp_word)j); sc0 = t; \
3750 t = sc1 + (t >> DIGIT_BIT); sc1 = t; sc2 += t >> DIGIT_BIT; \
3755 t = ((fp_word)sc0) + ((fp_word)sc0) + c0; c0 = t; \
3756 t = ((fp_word)sc1) + ((fp_word)sc1) + c1 + (t >> DIGIT_BIT); c1 = t; \
3757 c2 = c2 + ((fp_word)sc2) + ((fp_word)sc2) + (t >> DIGIT_BIT); \
3762 #include "fp_sqr_comba_generic.c"
3763 void fp_sqr_comba4(fp_int *A, fp_int *B)
3765 fp_digit *a, b[8], c0, c1, c2, sc0, sc1, sc2;
3779 SQRADD2(a[0], a[1]);
3784 SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
3789 SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
3794 SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
3799 SQRADD2(a[2], a[3]);
3811 memcpy(B->dp, b, 8 * sizeof(fp_digit));
3816 void fp_sqr_comba8(fp_int *A, fp_int *B)
3818 fp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2;
3832 SQRADD2(a[0], a[1]);
3837 SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
3842 SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
3847 SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
3852 SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
3857 SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
3862 SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
3867 SQRADDSC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
3872 SQRADDSC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
3877 SQRADD2(a[3], a[7]); SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]);
3882 SQRADD2(a[4], a[7]); SQRADD2(a[5], a[6]);
3887 SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]);
3892 SQRADD2(a[6], a[7]);
3899 COMBA_STORE2(b[15]);
3904 memcpy(B->dp, b, 16 * sizeof(fp_digit));
3910 void fp_sqr_comba16(fp_int *A, fp_int *B)
3912 fp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;
3926 SQRADD2(a[0], a[1]);
3931 SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
3936 SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
3941 SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
3946 SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
3951 SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
3956 SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
3961 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]);
3966 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;
3971 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]);
3976 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;
3981 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]);
3986 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;
3991 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]);
3996 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;
4001 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]);
4006 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;
4011 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]);
4016 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;
4021 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]);
4026 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;
4031 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]);
4036 SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
4041 SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
4046 SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
4051 SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]);
4056 SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]);
4061 SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]);
4066 SQRADD2(a[14], a[15]);
4071 SQRADD(a[15], a[15]);
4073 COMBA_STORE2(b[31]);
4078 memcpy(B->dp, b, 32 * sizeof(fp_digit));
4085 void fp_sqr_comba32(fp_int *A, fp_int *B)
4087 fp_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2;
4101 SQRADD2(a[0], a[1]);
4106 SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
4111 SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
4116 SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
4121 SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
4126 SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
4131 SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
4136 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]);
4141 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;
4146 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]);
4151 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;
4156 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]);
4161 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;
4166 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]);
4171 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;
4176 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]);
4181 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;
4186 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]);
4191 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;
4196 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]);
4201 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;
4206 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]);
4211 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;
4216 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]);
4221 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;
4226 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]);
4231 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;
4236 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]);
4241 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;
4246 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]);
4251 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;
4256 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]);
4261 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;
4266 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]);
4271 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;
4276 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]);
4281 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;
4286 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]);
4291 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;
4296 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]);
4301 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;
4306 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]);
4311 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;
4316 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]);
4321 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;
4326 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]);
4331 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;
4336 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]);
4341 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;
4346 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]);
4351 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;
4356 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]);
4361 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;
4366 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]);
4371 SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB;
4376 SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]);
4381 SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB;
4386 SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]);
4391 SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]);
4396 SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]);
4401 SQRADD2(a[30], a[31]);
4406 SQRADD(a[31], a[31]);
4408 COMBA_STORE2(b[63]);
4413 memcpy(B->dp, b, 64 * sizeof(fp_digit));
4421 void fp_sqr_comba64(fp_int *A, fp_int *B)
4423 fp_digit *a, b[128], c0, c1, c2, sc0, sc1, sc2;
4437 SQRADD2(a[0], a[1]);
4442 SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
4447 SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
4452 SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
4457 SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
4462 SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
4467 SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
4472 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]);
4477 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;
4482 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]);
4487 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;
4492 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]);
4497 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;
4502 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]);
4507 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;
4512 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]);
4517 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;
4522 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]);
4527 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;
4532 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]);
4537 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;
4542 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]);
4547 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;
4552 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]);
4557 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;
4562 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]);
4567 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;
4572 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]);
4577 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;
4582 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]);
4587 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;
4592 SQRADDSC(a[0], a[32]); SQRADDAC(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]);
4597 SQRADDSC(a[0], a[33]); SQRADDAC(a[1], a[32]); SQRADDAC(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;
4602 SQRADDSC(a[0], a[34]); SQRADDAC(a[1], a[33]); SQRADDAC(a[2], a[32]); SQRADDAC(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]);
4607 SQRADDSC(a[0], a[35]); SQRADDAC(a[1], a[34]); SQRADDAC(a[2], a[33]); SQRADDAC(a[3], a[32]); SQRADDAC(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;
4612 SQRADDSC(a[0], a[36]); SQRADDAC(a[1], a[35]); SQRADDAC(a[2], a[34]); SQRADDAC(a[3], a[33]); SQRADDAC(a[4], a[32]); SQRADDAC(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]);
4617 SQRADDSC(a[0], a[37]); SQRADDAC(a[1], a[36]); SQRADDAC(a[2], a[35]); SQRADDAC(a[3], a[34]); SQRADDAC(a[4], a[33]); SQRADDAC(a[5], a[32]); SQRADDAC(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;
4622 SQRADDSC(a[0], a[38]); SQRADDAC(a[1], a[37]); SQRADDAC(a[2], a[36]); SQRADDAC(a[3], a[35]); SQRADDAC(a[4], a[34]); SQRADDAC(a[5], a[33]); SQRADDAC(a[6], a[32]); SQRADDAC(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]);
4627 SQRADDSC(a[0], a[39]); SQRADDAC(a[1], a[38]); SQRADDAC(a[2], a[37]); SQRADDAC(a[3], a[36]); SQRADDAC(a[4], a[35]); SQRADDAC(a[5], a[34]); SQRADDAC(a[6], a[33]); SQRADDAC(a[7], a[32]); SQRADDAC(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;
4632 SQRADDSC(a[0], a[40]); SQRADDAC(a[1], a[39]); SQRADDAC(a[2], a[38]); SQRADDAC(a[3], a[37]); SQRADDAC(a[4], a[36]); SQRADDAC(a[5], a[35]); SQRADDAC(a[6], a[34]); SQRADDAC(a[7], a[33]); SQRADDAC(a[8], a[32]); SQRADDAC(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]);
4637 SQRADDSC(a[0], a[41]); SQRADDAC(a[1], a[40]); SQRADDAC(a[2], a[39]); SQRADDAC(a[3], a[38]); SQRADDAC(a[4], a[37]); SQRADDAC(a[5], a[36]); SQRADDAC(a[6], a[35]); SQRADDAC(a[7], a[34]); SQRADDAC(a[8], a[33]); SQRADDAC(a[9], a[32]); SQRADDAC(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;
4642 SQRADDSC(a[0], a[42]); SQRADDAC(a[1], a[41]); SQRADDAC(a[2], a[40]); SQRADDAC(a[3], a[39]); SQRADDAC(a[4], a[38]); SQRADDAC(a[5], a[37]); SQRADDAC(a[6], a[36]); SQRADDAC(a[7], a[35]); SQRADDAC(a[8], a[34]); SQRADDAC(a[9], a[33]); SQRADDAC(a[10], a[32]); SQRADDAC(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]);
4647 SQRADDSC(a[0], a[43]); SQRADDAC(a[1], a[42]); SQRADDAC(a[2], a[41]); SQRADDAC(a[3], a[40]); SQRADDAC(a[4], a[39]); SQRADDAC(a[5], a[38]); SQRADDAC(a[6], a[37]); SQRADDAC(a[7], a[36]); SQRADDAC(a[8], a[35]); SQRADDAC(a[9], a[34]); SQRADDAC(a[10], a[33]); SQRADDAC(a[11], a[32]); SQRADDAC(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;
4652 SQRADDSC(a[0], a[44]); SQRADDAC(a[1], a[43]); SQRADDAC(a[2], a[42]); SQRADDAC(a[3], a[41]); SQRADDAC(a[4], a[40]); SQRADDAC(a[5], a[39]); SQRADDAC(a[6], a[38]); SQRADDAC(a[7], a[37]); SQRADDAC(a[8], a[36]); SQRADDAC(a[9], a[35]); SQRADDAC(a[10], a[34]); SQRADDAC(a[11], a[33]); SQRADDAC(a[12], a[32]); SQRADDAC(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]);
4657 SQRADDSC(a[0], a[45]); SQRADDAC(a[1], a[44]); SQRADDAC(a[2], a[43]); SQRADDAC(a[3], a[42]); SQRADDAC(a[4], a[41]); SQRADDAC(a[5], a[40]); SQRADDAC(a[6], a[39]); SQRADDAC(a[7], a[38]); SQRADDAC(a[8], a[37]); SQRADDAC(a[9], a[36]); SQRADDAC(a[10], a[35]); SQRADDAC(a[11], a[34]); SQRADDAC(a[12], a[33]); SQRADDAC(a[13], a[32]); SQRADDAC(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;
4662 SQRADDSC(a[0], a[46]); SQRADDAC(a[1], a[45]); SQRADDAC(a[2], a[44]); SQRADDAC(a[3], a[43]); SQRADDAC(a[4], a[42]); SQRADDAC(a[5], a[41]); SQRADDAC(a[6], a[40]); SQRADDAC(a[7], a[39]); SQRADDAC(a[8], a[38]); SQRADDAC(a[9], a[37]); SQRADDAC(a[10], a[36]); SQRADDAC(a[11], a[35]); SQRADDAC(a[12], a[34]); SQRADDAC(a[13], a[33]); SQRADDAC(a[14], a[32]); SQRADDAC(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]);
4667 SQRADDSC(a[0], a[47]); SQRADDAC(a[1], a[46]); SQRADDAC(a[2], a[45]); SQRADDAC(a[3], a[44]); SQRADDAC(a[4], a[43]); SQRADDAC(a[5], a[42]); SQRADDAC(a[6], a[41]); SQRADDAC(a[7], a[40]); SQRADDAC(a[8], a[39]); SQRADDAC(a[9], a[38]); SQRADDAC(a[10], a[37]); SQRADDAC(a[11], a[36]); SQRADDAC(a[12], a[35]); SQRADDAC(a[13], a[34]); SQRADDAC(a[14], a[33]); SQRADDAC(a[15], a[32]); SQRADDAC(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;
4672 SQRADDSC(a[0], a[48]); SQRADDAC(a[1], a[47]); SQRADDAC(a[2], a[46]); SQRADDAC(a[3], a[45]); SQRADDAC(a[4], a[44]); SQRADDAC(a[5], a[43]); SQRADDAC(a[6], a[42]); SQRADDAC(a[7], a[41]); SQRADDAC(a[8], a[40]); SQRADDAC(a[9], a[39]); SQRADDAC(a[10], a[38]); SQRADDAC(a[11], a[37]); SQRADDAC(a[12], a[36]); SQRADDAC(a[13], a[35]); SQRADDAC(a[14], a[34]); SQRADDAC(a[15], a[33]); SQRADDAC(a[16], a[32]); SQRADDAC(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]);
4677 SQRADDSC(a[0], a[49]); SQRADDAC(a[1], a[48]); SQRADDAC(a[2], a[47]); SQRADDAC(a[3], a[46]); SQRADDAC(a[4], a[45]); SQRADDAC(a[5], a[44]); SQRADDAC(a[6], a[43]); SQRADDAC(a[7], a[42]); SQRADDAC(a[8], a[41]); SQRADDAC(a[9], a[40]); SQRADDAC(a[10], a[39]); SQRADDAC(a[11], a[38]); SQRADDAC(a[12], a[37]); SQRADDAC(a[13], a[36]); SQRADDAC(a[14], a[35]); SQRADDAC(a[15], a[34]); SQRADDAC(a[16], a[33]); SQRADDAC(a[17], a[32]); SQRADDAC(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;
4682 SQRADDSC(a[0], a[50]); SQRADDAC(a[1], a[49]); SQRADDAC(a[2], a[48]); SQRADDAC(a[3], a[47]); SQRADDAC(a[4], a[46]); SQRADDAC(a[5], a[45]); SQRADDAC(a[6], a[44]); SQRADDAC(a[7], a[43]); SQRADDAC(a[8], a[42]); SQRADDAC(a[9], a[41]); SQRADDAC(a[10], a[40]); SQRADDAC(a[11], a[39]); SQRADDAC(a[12], a[38]); SQRADDAC(a[13], a[37]); SQRADDAC(a[14], a[36]); SQRADDAC(a[15], a[35]); SQRADDAC(a[16], a[34]); SQRADDAC(a[17], a[33]); SQRADDAC(a[18], a[32]); SQRADDAC(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]);
4687 SQRADDSC(a[0], a[51]); SQRADDAC(a[1], a[50]); SQRADDAC(a[2], a[49]); SQRADDAC(a[3], a[48]); SQRADDAC(a[4], a[47]); SQRADDAC(a[5], a[46]); SQRADDAC(a[6], a[45]); SQRADDAC(a[7], a[44]); SQRADDAC(a[8], a[43]); SQRADDAC(a[9], a[42]); SQRADDAC(a[10], a[41]); SQRADDAC(a[11], a[40]); SQRADDAC(a[12], a[39]); SQRADDAC(a[13], a[38]); SQRADDAC(a[14], a[37]); SQRADDAC(a[15], a[36]); SQRADDAC(a[16], a[35]); SQRADDAC(a[17], a[34]); SQRADDAC(a[18], a[33]); SQRADDAC(a[19], a[32]); SQRADDAC(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;
4692 SQRADDSC(a[0], a[52]); SQRADDAC(a[1], a[51]); SQRADDAC(a[2], a[50]); SQRADDAC(a[3], a[49]); SQRADDAC(a[4], a[48]); SQRADDAC(a[5], a[47]); SQRADDAC(a[6], a[46]); SQRADDAC(a[7], a[45]); SQRADDAC(a[8], a[44]); SQRADDAC(a[9], a[43]); SQRADDAC(a[10], a[42]); SQRADDAC(a[11], a[41]); SQRADDAC(a[12], a[40]); SQRADDAC(a[13], a[39]); SQRADDAC(a[14], a[38]); SQRADDAC(a[15], a[37]); SQRADDAC(a[16], a[36]); SQRADDAC(a[17], a[35]); SQRADDAC(a[18], a[34]); SQRADDAC(a[19], a[33]); SQRADDAC(a[20], a[32]); SQRADDAC(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]);
4697 SQRADDSC(a[0], a[53]); SQRADDAC(a[1], a[52]); SQRADDAC(a[2], a[51]); SQRADDAC(a[3], a[50]); SQRADDAC(a[4], a[49]); SQRADDAC(a[5], a[48]); SQRADDAC(a[6], a[47]); SQRADDAC(a[7], a[46]); SQRADDAC(a[8], a[45]); SQRADDAC(a[9], a[44]); SQRADDAC(a[10], a[43]); SQRADDAC(a[11], a[42]); SQRADDAC(a[12], a[41]); SQRADDAC(a[13], a[40]); SQRADDAC(a[14], a[39]); SQRADDAC(a[15], a[38]); SQRADDAC(a[16], a[37]); SQRADDAC(a[17], a[36]); SQRADDAC(a[18], a[35]); SQRADDAC(a[19], a[34]); SQRADDAC(a[20], a[33]); SQRADDAC(a[21], a[32]); SQRADDAC(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;
4702 SQRADDSC(a[0], a[54]); SQRADDAC(a[1], a[53]); SQRADDAC(a[2], a[52]); SQRADDAC(a[3], a[51]); SQRADDAC(a[4], a[50]); SQRADDAC(a[5], a[49]); SQRADDAC(a[6], a[48]); SQRADDAC(a[7], a[47]); SQRADDAC(a[8], a[46]); SQRADDAC(a[9], a[45]); SQRADDAC(a[10], a[44]); SQRADDAC(a[11], a[43]); SQRADDAC(a[12], a[42]); SQRADDAC(a[13], a[41]); SQRADDAC(a[14], a[40]); SQRADDAC(a[15], a[39]); SQRADDAC(a[16], a[38]); SQRADDAC(a[17], a[37]); SQRADDAC(a[18], a[36]); SQRADDAC(a[19], a[35]); SQRADDAC(a[20], a[34]); SQRADDAC(a[21], a[33]); SQRADDAC(a[22], a[32]); SQRADDAC(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]);
4707 SQRADDSC(a[0], a[55]); SQRADDAC(a[1], a[54]); SQRADDAC(a[2], a[53]); SQRADDAC(a[3], a[52]); SQRADDAC(a[4], a[51]); SQRADDAC(a[5], a[50]); SQRADDAC(a[6], a[49]); SQRADDAC(a[7], a[48]); SQRADDAC(a[8], a[47]); SQRADDAC(a[9], a[46]); SQRADDAC(a[10], a[45]); SQRADDAC(a[11], a[44]); SQRADDAC(a[12], a[43]); SQRADDAC(a[13], a[42]); SQRADDAC(a[14], a[41]); SQRADDAC(a[15], a[40]); SQRADDAC(a[16], a[39]); SQRADDAC(a[17], a[38]); SQRADDAC(a[18], a[37]); SQRADDAC(a[19], a[36]); SQRADDAC(a[20], a[35]); SQRADDAC(a[21], a[34]); SQRADDAC(a[22], a[33]); SQRADDAC(a[23], a[32]); SQRADDAC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB;
4712 SQRADDSC(a[0], a[56]); SQRADDAC(a[1], a[55]); SQRADDAC(a[2], a[54]); SQRADDAC(a[3], a[53]); SQRADDAC(a[4], a[52]); SQRADDAC(a[5], a[51]); SQRADDAC(a[6], a[50]); SQRADDAC(a[7], a[49]); SQRADDAC(a[8], a[48]); SQRADDAC(a[9], a[47]); SQRADDAC(a[10], a[46]); SQRADDAC(a[11], a[45]); SQRADDAC(a[12], a[44]); SQRADDAC(a[13], a[43]); SQRADDAC(a[14], a[42]); SQRADDAC(a[15], a[41]); SQRADDAC(a[16], a[40]); SQRADDAC(a[17], a[39]); SQRADDAC(a[18], a[38]); SQRADDAC(a[19], a[37]); SQRADDAC(a[20], a[36]); SQRADDAC(a[21], a[35]); SQRADDAC(a[22], a[34]); SQRADDAC(a[23], a[33]); SQRADDAC(a[24], a[32]); SQRADDAC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]);
4717 SQRADDSC(a[0], a[57]); SQRADDAC(a[1], a[56]); SQRADDAC(a[2], a[55]); SQRADDAC(a[3], a[54]); SQRADDAC(a[4], a[53]); SQRADDAC(a[5], a[52]); SQRADDAC(a[6], a[51]); SQRADDAC(a[7], a[50]); SQRADDAC(a[8], a[49]); SQRADDAC(a[9], a[48]); SQRADDAC(a[10], a[47]); SQRADDAC(a[11], a[46]); SQRADDAC(a[12], a[45]); SQRADDAC(a[13], a[44]); SQRADDAC(a[14], a[43]); SQRADDAC(a[15], a[42]); SQRADDAC(a[16], a[41]); SQRADDAC(a[17], a[40]); SQRADDAC(a[18], a[39]); SQRADDAC(a[19], a[38]); SQRADDAC(a[20], a[37]); SQRADDAC(a[21], a[36]); SQRADDAC(a[22], a[35]); SQRADDAC(a[23], a[34]); SQRADDAC(a[24], a[33]); SQRADDAC(a[25], a[32]); SQRADDAC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB;
4722 SQRADDSC(a[0], a[58]); SQRADDAC(a[1], a[57]); SQRADDAC(a[2], a[56]); SQRADDAC(a[3], a[55]); SQRADDAC(a[4], a[54]); SQRADDAC(a[5], a[53]); SQRADDAC(a[6], a[52]); SQRADDAC(a[7], a[51]); SQRADDAC(a[8], a[50]); SQRADDAC(a[9], a[49]); SQRADDAC(a[10], a[48]); SQRADDAC(a[11], a[47]); SQRADDAC(a[12], a[46]); SQRADDAC(a[13], a[45]); SQRADDAC(a[14], a[44]); SQRADDAC(a[15], a[43]); SQRADDAC(a[16], a[42]); SQRADDAC(a[17], a[41]); SQRADDAC(a[18], a[40]); SQRADDAC(a[19], a[39]); SQRADDAC(a[20], a[38]); SQRADDAC(a[21], a[37]); SQRADDAC(a[22], a[36]); SQRADDAC(a[23], a[35]); SQRADDAC(a[24], a[34]); SQRADDAC(a[25], a[33]); SQRADDAC(a[26], a[32]); SQRADDAC(a[27], a[31]); SQRADDAC(a[28], a[30]); SQRADDDB; SQRADD(a[29], a[29]);
4727 SQRADDSC(a[0], a[59]); SQRADDAC(a[1], a[58]); SQRADDAC(a[2], a[57]); SQRADDAC(a[3], a[56]); SQRADDAC(a[4], a[55]); SQRADDAC(a[5], a[54]); SQRADDAC(a[6], a[53]); SQRADDAC(a[7], a[52]); SQRADDAC(a[8], a[51]); SQRADDAC(a[9], a[50]); SQRADDAC(a[10], a[49]); SQRADDAC(a[11], a[48]); SQRADDAC(a[12], a[47]); SQRADDAC(a[13], a[46]); SQRADDAC(a[14], a[45]); SQRADDAC(a[15], a[44]); SQRADDAC(a[16], a[43]); SQRADDAC(a[17], a[42]); SQRADDAC(a[18], a[41]); SQRADDAC(a[19], a[40]); SQRADDAC(a[20], a[39]); SQRADDAC(a[21], a[38]); SQRADDAC(a[22], a[37]); SQRADDAC(a[23], a[36]); SQRADDAC(a[24], a[35]); SQRADDAC(a[25], a[34]); SQRADDAC(a[26], a[33]); SQRADDAC(a[27], a[32]); SQRADDAC(a[28], a[31]); SQRADDAC(a[29], a[30]); SQRADDDB;
4732 SQRADDSC(a[0], a[60]); SQRADDAC(a[1], a[59]); SQRADDAC(a[2], a[58]); SQRADDAC(a[3], a[57]); SQRADDAC(a[4], a[56]); SQRADDAC(a[5], a[55]); SQRADDAC(a[6], a[54]); SQRADDAC(a[7], a[53]); SQRADDAC(a[8], a[52]); SQRADDAC(a[9], a[51]); SQRADDAC(a[10], a[50]); SQRADDAC(a[11], a[49]); SQRADDAC(a[12], a[48]); SQRADDAC(a[13], a[47]); SQRADDAC(a[14], a[46]); SQRADDAC(a[15], a[45]); SQRADDAC(a[16], a[44]); SQRADDAC(a[17], a[43]); SQRADDAC(a[18], a[42]); SQRADDAC(a[19], a[41]); SQRADDAC(a[20], a[40]); SQRADDAC(a[21], a[39]); SQRADDAC(a[22], a[38]); SQRADDAC(a[23], a[37]); SQRADDAC(a[24], a[36]); SQRADDAC(a[25], a[35]); SQRADDAC(a[26], a[34]); SQRADDAC(a[27], a[33]); SQRADDAC(a[28], a[32]); SQRADDAC(a[29], a[31]); SQRADDDB; SQRADD(a[30], a[30]);
4737 SQRADDSC(a[0], a[61]); SQRADDAC(a[1], a[60]); SQRADDAC(a[2], a[59]); SQRADDAC(a[3], a[58]); SQRADDAC(a[4], a[57]); SQRADDAC(a[5], a[56]); SQRADDAC(a[6], a[55]); SQRADDAC(a[7], a[54]); SQRADDAC(a[8], a[53]); SQRADDAC(a[9], a[52]); SQRADDAC(a[10], a[51]); SQRADDAC(a[11], a[50]); SQRADDAC(a[12], a[49]); SQRADDAC(a[13], a[48]); SQRADDAC(a[14], a[47]); SQRADDAC(a[15], a[46]); SQRADDAC(a[16], a[45]); SQRADDAC(a[17], a[44]); SQRADDAC(a[18], a[43]); SQRADDAC(a[19], a[42]); SQRADDAC(a[20], a[41]); SQRADDAC(a[21], a[40]); SQRADDAC(a[22], a[39]); SQRADDAC(a[23], a[38]); SQRADDAC(a[24], a[37]); SQRADDAC(a[25], a[36]); SQRADDAC(a[26], a[35]); SQRADDAC(a[27], a[34]); SQRADDAC(a[28], a[33]); SQRADDAC(a[29], a[32]); SQRADDAC(a[30], a[31]); SQRADDDB;
4742 SQRADDSC(a[0], a[62]); SQRADDAC(a[1], a[61]); SQRADDAC(a[2], a[60]); SQRADDAC(a[3], a[59]); SQRADDAC(a[4], a[58]); SQRADDAC(a[5], a[57]); SQRADDAC(a[6], a[56]); SQRADDAC(a[7], a[55]); SQRADDAC(a[8], a[54]); SQRADDAC(a[9], a[53]); SQRADDAC(a[10], a[52]); SQRADDAC(a[11], a[51]); SQRADDAC(a[12], a[50]); SQRADDAC(a[13], a[49]); SQRADDAC(a[14], a[48]); SQRADDAC(a[15], a[47]); SQRADDAC(a[16], a[46]); SQRADDAC(a[17], a[45]); SQRADDAC(a[18], a[44]); SQRADDAC(a[19], a[43]); SQRADDAC(a[20], a[42]); SQRADDAC(a[21], a[41]); SQRADDAC(a[22], a[40]); SQRADDAC(a[23], a[39]); SQRADDAC(a[24], a[38]); SQRADDAC(a[25], a[37]); SQRADDAC(a[26], a[36]); SQRADDAC(a[27], a[35]); SQRADDAC(a[28], a[34]); SQRADDAC(a[29], a[33]); SQRADDAC(a[30], a[32]); SQRADDDB; SQRADD(a[31], a[31]);
4747 SQRADDSC(a[0], a[63]); SQRADDAC(a[1], a[62]); SQRADDAC(a[2], a[61]); SQRADDAC(a[3], a[60]); SQRADDAC(a[4], a[59]); SQRADDAC(a[5], a[58]); SQRADDAC(a[6], a[57]); SQRADDAC(a[7], a[56]); SQRADDAC(a[8], a[55]); SQRADDAC(a[9], a[54]); SQRADDAC(a[10], a[53]); SQRADDAC(a[11], a[52]); SQRADDAC(a[12], a[51]); SQRADDAC(a[13], a[50]); SQRADDAC(a[14], a[49]); SQRADDAC(a[15], a[48]); SQRADDAC(a[16], a[47]); SQRADDAC(a[17], a[46]); SQRADDAC(a[18], a[45]); SQRADDAC(a[19], a[44]); SQRADDAC(a[20], a[43]); SQRADDAC(a[21], a[42]); SQRADDAC(a[22], a[41]); SQRADDAC(a[23], a[40]); SQRADDAC(a[24], a[39]); SQRADDAC(a[25], a[38]); SQRADDAC(a[26], a[37]); SQRADDAC(a[27], a[36]); SQRADDAC(a[28], a[35]); SQRADDAC(a[29], a[34]); SQRADDAC(a[30], a[33]); SQRADDAC(a[31], a[32]); SQRADDDB;
4752 SQRADDSC(a[1], a[63]); SQRADDAC(a[2], a[62]); SQRADDAC(a[3], a[61]); SQRADDAC(a[4], a[60]); SQRADDAC(a[5], a[59]); SQRADDAC(a[6], a[58]); SQRADDAC(a[7], a[57]); SQRADDAC(a[8], a[56]); SQRADDAC(a[9], a[55]); SQRADDAC(a[10], a[54]); SQRADDAC(a[11], a[53]); SQRADDAC(a[12], a[52]); SQRADDAC(a[13], a[51]); SQRADDAC(a[14], a[50]); SQRADDAC(a[15], a[49]); SQRADDAC(a[16], a[48]); SQRADDAC(a[17], a[47]); SQRADDAC(a[18], a[46]); SQRADDAC(a[19], a[45]); SQRADDAC(a[20], a[44]); SQRADDAC(a[21], a[43]); SQRADDAC(a[22], a[42]); SQRADDAC(a[23], a[41]); SQRADDAC(a[24], a[40]); SQRADDAC(a[25], a[39]); SQRADDAC(a[26], a[38]); SQRADDAC(a[27], a[37]); SQRADDAC(a[28], a[36]); SQRADDAC(a[29], a[35]); SQRADDAC(a[30], a[34]); SQRADDAC(a[31], a[33]); SQRADDDB; SQRADD(a[32], a[32]);
4757 SQRADDSC(a[2], a[63]); SQRADDAC(a[3], a[62]); SQRADDAC(a[4], a[61]); SQRADDAC(a[5], a[60]); SQRADDAC(a[6], a[59]); SQRADDAC(a[7], a[58]); SQRADDAC(a[8], a[57]); SQRADDAC(a[9], a[56]); SQRADDAC(a[10], a[55]); SQRADDAC(a[11], a[54]); SQRADDAC(a[12], a[53]); SQRADDAC(a[13], a[52]); SQRADDAC(a[14], a[51]); SQRADDAC(a[15], a[50]); SQRADDAC(a[16], a[49]); SQRADDAC(a[17], a[48]); SQRADDAC(a[18], a[47]); SQRADDAC(a[19], a[46]); SQRADDAC(a[20], a[45]); SQRADDAC(a[21], a[44]); SQRADDAC(a[22], a[43]); SQRADDAC(a[23], a[42]); SQRADDAC(a[24], a[41]); SQRADDAC(a[25], a[40]); SQRADDAC(a[26], a[39]); SQRADDAC(a[27], a[38]); SQRADDAC(a[28], a[37]); SQRADDAC(a[29], a[36]); SQRADDAC(a[30], a[35]); SQRADDAC(a[31], a[34]); SQRADDAC(a[32], a[33]); SQRADDDB;
4762 SQRADDSC(a[3], a[63]); SQRADDAC(a[4], a[62]); SQRADDAC(a[5], a[61]); SQRADDAC(a[6], a[60]); SQRADDAC(a[7], a[59]); SQRADDAC(a[8], a[58]); SQRADDAC(a[9], a[57]); SQRADDAC(a[10], a[56]); SQRADDAC(a[11], a[55]); SQRADDAC(a[12], a[54]); SQRADDAC(a[13], a[53]); SQRADDAC(a[14], a[52]); SQRADDAC(a[15], a[51]); SQRADDAC(a[16], a[50]); SQRADDAC(a[17], a[49]); SQRADDAC(a[18], a[48]); SQRADDAC(a[19], a[47]); SQRADDAC(a[20], a[46]); SQRADDAC(a[21], a[45]); SQRADDAC(a[22], a[44]); SQRADDAC(a[23], a[43]); SQRADDAC(a[24], a[42]); SQRADDAC(a[25], a[41]); SQRADDAC(a[26], a[40]); SQRADDAC(a[27], a[39]); SQRADDAC(a[28], a[38]); SQRADDAC(a[29], a[37]); SQRADDAC(a[30], a[36]); SQRADDAC(a[31], a[35]); SQRADDAC(a[32], a[34]); SQRADDDB; SQRADD(a[33], a[33]);
4767 SQRADDSC(a[4], a[63]); SQRADDAC(a[5], a[62]); SQRADDAC(a[6], a[61]); SQRADDAC(a[7], a[60]); SQRADDAC(a[8], a[59]); SQRADDAC(a[9], a[58]); SQRADDAC(a[10], a[57]); SQRADDAC(a[11], a[56]); SQRADDAC(a[12], a[55]); SQRADDAC(a[13], a[54]); SQRADDAC(a[14], a[53]); SQRADDAC(a[15], a[52]); SQRADDAC(a[16], a[51]); SQRADDAC(a[17], a[50]); SQRADDAC(a[18], a[49]); SQRADDAC(a[19], a[48]); SQRADDAC(a[20], a[47]); SQRADDAC(a[21], a[46]); SQRADDAC(a[22], a[45]); SQRADDAC(a[23], a[44]); SQRADDAC(a[24], a[43]); SQRADDAC(a[25], a[42]); SQRADDAC(a[26], a[41]); SQRADDAC(a[27], a[40]); SQRADDAC(a[28], a[39]); SQRADDAC(a[29], a[38]); SQRADDAC(a[30], a[37]); SQRADDAC(a[31], a[36]); SQRADDAC(a[32], a[35]); SQRADDAC(a[33], a[34]); SQRADDDB;
4772 SQRADDSC(a[5], a[63]); SQRADDAC(a[6], a[62]); SQRADDAC(a[7], a[61]); SQRADDAC(a[8], a[60]); SQRADDAC(a[9], a[59]); SQRADDAC(a[10], a[58]); SQRADDAC(a[11], a[57]); SQRADDAC(a[12], a[56]); SQRADDAC(a[13], a[55]); SQRADDAC(a[14], a[54]); SQRADDAC(a[15], a[53]); SQRADDAC(a[16], a[52]); SQRADDAC(a[17], a[51]); SQRADDAC(a[18], a[50]); SQRADDAC(a[19], a[49]); SQRADDAC(a[20], a[48]); SQRADDAC(a[21], a[47]); SQRADDAC(a[22], a[46]); SQRADDAC(a[23], a[45]); SQRADDAC(a[24], a[44]); SQRADDAC(a[25], a[43]); SQRADDAC(a[26], a[42]); SQRADDAC(a[27], a[41]); SQRADDAC(a[28], a[40]); SQRADDAC(a[29], a[39]); SQRADDAC(a[30], a[38]); SQRADDAC(a[31], a[37]); SQRADDAC(a[32], a[36]); SQRADDAC(a[33], a[35]); SQRADDDB; SQRADD(a[34], a[34]);
4777 SQRADDSC(a[6], a[63]); SQRADDAC(a[7], a[62]); SQRADDAC(a[8], a[61]); SQRADDAC(a[9], a[60]); SQRADDAC(a[10], a[59]); SQRADDAC(a[11], a[58]); SQRADDAC(a[12], a[57]); SQRADDAC(a[13], a[56]); SQRADDAC(a[14], a[55]); SQRADDAC(a[15], a[54]); SQRADDAC(a[16], a[53]); SQRADDAC(a[17], a[52]); SQRADDAC(a[18], a[51]); SQRADDAC(a[19], a[50]); SQRADDAC(a[20], a[49]); SQRADDAC(a[21], a[48]); SQRADDAC(a[22], a[47]); SQRADDAC(a[23], a[46]); SQRADDAC(a[24], a[45]); SQRADDAC(a[25], a[44]); SQRADDAC(a[26], a[43]); SQRADDAC(a[27], a[42]); SQRADDAC(a[28], a[41]); SQRADDAC(a[29], a[40]); SQRADDAC(a[30], a[39]); SQRADDAC(a[31], a[38]); SQRADDAC(a[32], a[37]); SQRADDAC(a[33], a[36]); SQRADDAC(a[34], a[35]); SQRADDDB;
4782 SQRADDSC(a[7], a[63]); SQRADDAC(a[8], a[62]); SQRADDAC(a[9], a[61]); SQRADDAC(a[10], a[60]); SQRADDAC(a[11], a[59]); SQRADDAC(a[12], a[58]); SQRADDAC(a[13], a[57]); SQRADDAC(a[14], a[56]); SQRADDAC(a[15], a[55]); SQRADDAC(a[16], a[54]); SQRADDAC(a[17], a[53]); SQRADDAC(a[18], a[52]); SQRADDAC(a[19], a[51]); SQRADDAC(a[20], a[50]); SQRADDAC(a[21], a[49]); SQRADDAC(a[22], a[48]); SQRADDAC(a[23], a[47]); SQRADDAC(a[24], a[46]); SQRADDAC(a[25], a[45]); SQRADDAC(a[26], a[44]); SQRADDAC(a[27], a[43]); SQRADDAC(a[28], a[42]); SQRADDAC(a[29], a[41]); SQRADDAC(a[30], a[40]); SQRADDAC(a[31], a[39]); SQRADDAC(a[32], a[38]); SQRADDAC(a[33], a[37]); SQRADDAC(a[34], a[36]); SQRADDDB; SQRADD(a[35], a[35]);
4787 SQRADDSC(a[8], a[63]); SQRADDAC(a[9], a[62]); SQRADDAC(a[10], a[61]); SQRADDAC(a[11], a[60]); SQRADDAC(a[12], a[59]); SQRADDAC(a[13], a[58]); SQRADDAC(a[14], a[57]); SQRADDAC(a[15], a[56]); SQRADDAC(a[16], a[55]); SQRADDAC(a[17], a[54]); SQRADDAC(a[18], a[53]); SQRADDAC(a[19], a[52]); SQRADDAC(a[20], a[51]); SQRADDAC(a[21], a[50]); SQRADDAC(a[22], a[49]); SQRADDAC(a[23], a[48]); SQRADDAC(a[24], a[47]); SQRADDAC(a[25], a[46]); SQRADDAC(a[26], a[45]); SQRADDAC(a[27], a[44]); SQRADDAC(a[28], a[43]); SQRADDAC(a[29], a[42]); SQRADDAC(a[30], a[41]); SQRADDAC(a[31], a[40]); SQRADDAC(a[32], a[39]); SQRADDAC(a[33], a[38]); SQRADDAC(a[34], a[37]); SQRADDAC(a[35], a[36]); SQRADDDB;
4792 SQRADDSC(a[9], a[63]); SQRADDAC(a[10], a[62]); SQRADDAC(a[11], a[61]); SQRADDAC(a[12], a[60]); SQRADDAC(a[13], a[59]); SQRADDAC(a[14], a[58]); SQRADDAC(a[15], a[57]); SQRADDAC(a[16], a[56]); SQRADDAC(a[17], a[55]); SQRADDAC(a[18], a[54]); SQRADDAC(a[19], a[53]); SQRADDAC(a[20], a[52]); SQRADDAC(a[21], a[51]); SQRADDAC(a[22], a[50]); SQRADDAC(a[23], a[49]); SQRADDAC(a[24], a[48]); SQRADDAC(a[25], a[47]); SQRADDAC(a[26], a[46]); SQRADDAC(a[27], a[45]); SQRADDAC(a[28], a[44]); SQRADDAC(a[29], a[43]); SQRADDAC(a[30], a[42]); SQRADDAC(a[31], a[41]); SQRADDAC(a[32], a[40]); SQRADDAC(a[33], a[39]); SQRADDAC(a[34], a[38]); SQRADDAC(a[35], a[37]); SQRADDDB; SQRADD(a[36], a[36]);
4797 SQRADDSC(a[10], a[63]); SQRADDAC(a[11], a[62]); SQRADDAC(a[12], a[61]); SQRADDAC(a[13], a[60]); SQRADDAC(a[14], a[59]); SQRADDAC(a[15], a[58]); SQRADDAC(a[16], a[57]); SQRADDAC(a[17], a[56]); SQRADDAC(a[18], a[55]); SQRADDAC(a[19], a[54]); SQRADDAC(a[20], a[53]); SQRADDAC(a[21], a[52]); SQRADDAC(a[22], a[51]); SQRADDAC(a[23], a[50]); SQRADDAC(a[24], a[49]); SQRADDAC(a[25], a[48]); SQRADDAC(a[26], a[47]); SQRADDAC(a[27], a[46]); SQRADDAC(a[28], a[45]); SQRADDAC(a[29], a[44]); SQRADDAC(a[30], a[43]); SQRADDAC(a[31], a[42]); SQRADDAC(a[32], a[41]); SQRADDAC(a[33], a[40]); SQRADDAC(a[34], a[39]); SQRADDAC(a[35], a[38]); SQRADDAC(a[36], a[37]); SQRADDDB;
4802 SQRADDSC(a[11], a[63]); SQRADDAC(a[12], a[62]); SQRADDAC(a[13], a[61]); SQRADDAC(a[14], a[60]); SQRADDAC(a[15], a[59]); SQRADDAC(a[16], a[58]); SQRADDAC(a[17], a[57]); SQRADDAC(a[18], a[56]); SQRADDAC(a[19], a[55]); SQRADDAC(a[20], a[54]); SQRADDAC(a[21], a[53]); SQRADDAC(a[22], a[52]); SQRADDAC(a[23], a[51]); SQRADDAC(a[24], a[50]); SQRADDAC(a[25], a[49]); SQRADDAC(a[26], a[48]); SQRADDAC(a[27], a[47]); SQRADDAC(a[28], a[46]); SQRADDAC(a[29], a[45]); SQRADDAC(a[30], a[44]); SQRADDAC(a[31], a[43]); SQRADDAC(a[32], a[42]); SQRADDAC(a[33], a[41]); SQRADDAC(a[34], a[40]); SQRADDAC(a[35], a[39]); SQRADDAC(a[36], a[38]); SQRADDDB; SQRADD(a[37], a[37]);
4807 SQRADDSC(a[12], a[63]); SQRADDAC(a[13], a[62]); SQRADDAC(a[14], a[61]); SQRADDAC(a[15], a[60]); SQRADDAC(a[16], a[59]); SQRADDAC(a[17], a[58]); SQRADDAC(a[18], a[57]); SQRADDAC(a[19], a[56]); SQRADDAC(a[20], a[55]); SQRADDAC(a[21], a[54]); SQRADDAC(a[22], a[53]); SQRADDAC(a[23], a[52]); SQRADDAC(a[24], a[51]); SQRADDAC(a[25], a[50]); SQRADDAC(a[26], a[49]); SQRADDAC(a[27], a[48]); SQRADDAC(a[28], a[47]); SQRADDAC(a[29], a[46]); SQRADDAC(a[30], a[45]); SQRADDAC(a[31], a[44]); SQRADDAC(a[32], a[43]); SQRADDAC(a[33], a[42]); SQRADDAC(a[34], a[41]); SQRADDAC(a[35], a[40]); SQRADDAC(a[36], a[39]); SQRADDAC(a[37], a[38]); SQRADDDB;
4812 SQRADDSC(a[13], a[63]); SQRADDAC(a[14], a[62]); SQRADDAC(a[15], a[61]); SQRADDAC(a[16], a[60]); SQRADDAC(a[17], a[59]); SQRADDAC(a[18], a[58]); SQRADDAC(a[19], a[57]); SQRADDAC(a[20], a[56]); SQRADDAC(a[21], a[55]); SQRADDAC(a[22], a[54]); SQRADDAC(a[23], a[53]); SQRADDAC(a[24], a[52]); SQRADDAC(a[25], a[51]); SQRADDAC(a[26], a[50]); SQRADDAC(a[27], a[49]); SQRADDAC(a[28], a[48]); SQRADDAC(a[29], a[47]); SQRADDAC(a[30], a[46]); SQRADDAC(a[31], a[45]); SQRADDAC(a[32], a[44]); SQRADDAC(a[33], a[43]); SQRADDAC(a[34], a[42]); SQRADDAC(a[35], a[41]); SQRADDAC(a[36], a[40]); SQRADDAC(a[37], a[39]); SQRADDDB; SQRADD(a[38], a[38]);
4817 SQRADDSC(a[14], a[63]); SQRADDAC(a[15], a[62]); SQRADDAC(a[16], a[61]); SQRADDAC(a[17], a[60]); SQRADDAC(a[18], a[59]); SQRADDAC(a[19], a[58]); SQRADDAC(a[20], a[57]); SQRADDAC(a[21], a[56]); SQRADDAC(a[22], a[55]); SQRADDAC(a[23], a[54]); SQRADDAC(a[24], a[53]); SQRADDAC(a[25], a[52]); SQRADDAC(a[26], a[51]); SQRADDAC(a[27], a[50]); SQRADDAC(a[28], a[49]); SQRADDAC(a[29], a[48]); SQRADDAC(a[30], a[47]); SQRADDAC(a[31], a[46]); SQRADDAC(a[32], a[45]); SQRADDAC(a[33], a[44]); SQRADDAC(a[34], a[43]); SQRADDAC(a[35], a[42]); SQRADDAC(a[36], a[41]); SQRADDAC(a[37], a[40]); SQRADDAC(a[38], a[39]); SQRADDDB;
4822 SQRADDSC(a[15], a[63]); SQRADDAC(a[16], a[62]); SQRADDAC(a[17], a[61]); SQRADDAC(a[18], a[60]); SQRADDAC(a[19], a[59]); SQRADDAC(a[20], a[58]); SQRADDAC(a[21], a[57]); SQRADDAC(a[22], a[56]); SQRADDAC(a[23], a[55]); SQRADDAC(a[24], a[54]); SQRADDAC(a[25], a[53]); SQRADDAC(a[26], a[52]); SQRADDAC(a[27], a[51]); SQRADDAC(a[28], a[50]); SQRADDAC(a[29], a[49]); SQRADDAC(a[30], a[48]); SQRADDAC(a[31], a[47]); SQRADDAC(a[32], a[46]); SQRADDAC(a[33], a[45]); SQRADDAC(a[34], a[44]); SQRADDAC(a[35], a[43]); SQRADDAC(a[36], a[42]); SQRADDAC(a[37], a[41]); SQRADDAC(a[38], a[40]); SQRADDDB; SQRADD(a[39], a[39]);
4827 SQRADDSC(a[16], a[63]); SQRADDAC(a[17], a[62]); SQRADDAC(a[18], a[61]); SQRADDAC(a[19], a[60]); SQRADDAC(a[20], a[59]); SQRADDAC(a[21], a[58]); SQRADDAC(a[22], a[57]); SQRADDAC(a[23], a[56]); SQRADDAC(a[24], a[55]); SQRADDAC(a[25], a[54]); SQRADDAC(a[26], a[53]); SQRADDAC(a[27], a[52]); SQRADDAC(a[28], a[51]); SQRADDAC(a[29], a[50]); SQRADDAC(a[30], a[49]); SQRADDAC(a[31], a[48]); SQRADDAC(a[32], a[47]); SQRADDAC(a[33], a[46]); SQRADDAC(a[34], a[45]); SQRADDAC(a[35], a[44]); SQRADDAC(a[36], a[43]); SQRADDAC(a[37], a[42]); SQRADDAC(a[38], a[41]); SQRADDAC(a[39], a[40]); SQRADDDB;
4832 SQRADDSC(a[17], a[63]); SQRADDAC(a[18], a[62]); SQRADDAC(a[19], a[61]); SQRADDAC(a[20], a[60]); SQRADDAC(a[21], a[59]); SQRADDAC(a[22], a[58]); SQRADDAC(a[23], a[57]); SQRADDAC(a[24], a[56]); SQRADDAC(a[25], a[55]); SQRADDAC(a[26], a[54]); SQRADDAC(a[27], a[53]); SQRADDAC(a[28], a[52]); SQRADDAC(a[29], a[51]); SQRADDAC(a[30], a[50]); SQRADDAC(a[31], a[49]); SQRADDAC(a[32], a[48]); SQRADDAC(a[33], a[47]); SQRADDAC(a[34], a[46]); SQRADDAC(a[35], a[45]); SQRADDAC(a[36], a[44]); SQRADDAC(a[37], a[43]); SQRADDAC(a[38], a[42]); SQRADDAC(a[39], a[41]); SQRADDDB; SQRADD(a[40], a[40]);
4837 SQRADDSC(a[18], a[63]); SQRADDAC(a[19], a[62]); SQRADDAC(a[20], a[61]); SQRADDAC(a[21], a[60]); SQRADDAC(a[22], a[59]); SQRADDAC(a[23], a[58]); SQRADDAC(a[24], a[57]); SQRADDAC(a[25], a[56]); SQRADDAC(a[26], a[55]); SQRADDAC(a[27], a[54]); SQRADDAC(a[28], a[53]); SQRADDAC(a[29], a[52]); SQRADDAC(a[30], a[51]); SQRADDAC(a[31], a[50]); SQRADDAC(a[32], a[49]); SQRADDAC(a[33], a[48]); SQRADDAC(a[34], a[47]); SQRADDAC(a[35], a[46]); SQRADDAC(a[36], a[45]); SQRADDAC(a[37], a[44]); SQRADDAC(a[38], a[43]); SQRADDAC(a[39], a[42]); SQRADDAC(a[40], a[41]); SQRADDDB;
4842 SQRADDSC(a[19], a[63]); SQRADDAC(a[20], a[62]); SQRADDAC(a[21], a[61]); SQRADDAC(a[22], a[60]); SQRADDAC(a[23], a[59]); SQRADDAC(a[24], a[58]); SQRADDAC(a[25], a[57]); SQRADDAC(a[26], a[56]); SQRADDAC(a[27], a[55]); SQRADDAC(a[28], a[54]); SQRADDAC(a[29], a[53]); SQRADDAC(a[30], a[52]); SQRADDAC(a[31], a[51]); SQRADDAC(a[32], a[50]); SQRADDAC(a[33], a[49]); SQRADDAC(a[34], a[48]); SQRADDAC(a[35], a[47]); SQRADDAC(a[36], a[46]); SQRADDAC(a[37], a[45]); SQRADDAC(a[38], a[44]); SQRADDAC(a[39], a[43]); SQRADDAC(a[40], a[42]); SQRADDDB; SQRADD(a[41], a[41]);
4847 SQRADDSC(a[20], a[63]); SQRADDAC(a[21], a[62]); SQRADDAC(a[22], a[61]); SQRADDAC(a[23], a[60]); SQRADDAC(a[24], a[59]); SQRADDAC(a[25], a[58]); SQRADDAC(a[26], a[57]); SQRADDAC(a[27], a[56]); SQRADDAC(a[28], a[55]); SQRADDAC(a[29], a[54]); SQRADDAC(a[30], a[53]); SQRADDAC(a[31], a[52]); SQRADDAC(a[32], a[51]); SQRADDAC(a[33], a[50]); SQRADDAC(a[34], a[49]); SQRADDAC(a[35], a[48]); SQRADDAC(a[36], a[47]); SQRADDAC(a[37], a[46]); SQRADDAC(a[38], a[45]); SQRADDAC(a[39], a[44]); SQRADDAC(a[40], a[43]); SQRADDAC(a[41], a[42]); SQRADDDB;
4852 SQRADDSC(a[21], a[63]); SQRADDAC(a[22], a[62]); SQRADDAC(a[23], a[61]); SQRADDAC(a[24], a[60]); SQRADDAC(a[25], a[59]); SQRADDAC(a[26], a[58]); SQRADDAC(a[27], a[57]); SQRADDAC(a[28], a[56]); SQRADDAC(a[29], a[55]); SQRADDAC(a[30], a[54]); SQRADDAC(a[31], a[53]); SQRADDAC(a[32], a[52]); SQRADDAC(a[33], a[51]); SQRADDAC(a[34], a[50]); SQRADDAC(a[35], a[49]); SQRADDAC(a[36], a[48]); SQRADDAC(a[37], a[47]); SQRADDAC(a[38], a[46]); SQRADDAC(a[39], a[45]); SQRADDAC(a[40], a[44]); SQRADDAC(a[41], a[43]); SQRADDDB; SQRADD(a[42], a[42]);
4857 SQRADDSC(a[22], a[63]); SQRADDAC(a[23], a[62]); SQRADDAC(a[24], a[61]); SQRADDAC(a[25], a[60]); SQRADDAC(a[26], a[59]); SQRADDAC(a[27], a[58]); SQRADDAC(a[28], a[57]); SQRADDAC(a[29], a[56]); SQRADDAC(a[30], a[55]); SQRADDAC(a[31], a[54]); SQRADDAC(a[32], a[53]); SQRADDAC(a[33], a[52]); SQRADDAC(a[34], a[51]); SQRADDAC(a[35], a[50]); SQRADDAC(a[36], a[49]); SQRADDAC(a[37], a[48]); SQRADDAC(a[38], a[47]); SQRADDAC(a[39], a[46]); SQRADDAC(a[40], a[45]); SQRADDAC(a[41], a[44]); SQRADDAC(a[42], a[43]); SQRADDDB;
4862 SQRADDSC(a[23], a[63]); SQRADDAC(a[24], a[62]); SQRADDAC(a[25], a[61]); SQRADDAC(a[26], a[60]); SQRADDAC(a[27], a[59]); SQRADDAC(a[28], a[58]); SQRADDAC(a[29], a[57]); SQRADDAC(a[30], a[56]); SQRADDAC(a[31], a[55]); SQRADDAC(a[32], a[54]); SQRADDAC(a[33], a[53]); SQRADDAC(a[34], a[52]); SQRADDAC(a[35], a[51]); SQRADDAC(a[36], a[50]); SQRADDAC(a[37], a[49]); SQRADDAC(a[38], a[48]); SQRADDAC(a[39], a[47]); SQRADDAC(a[40], a[46]); SQRADDAC(a[41], a[45]); SQRADDAC(a[42], a[44]); SQRADDDB; SQRADD(a[43], a[43]);
4867 SQRADDSC(a[24], a[63]); SQRADDAC(a[25], a[62]); SQRADDAC(a[26], a[61]); SQRADDAC(a[27], a[60]); SQRADDAC(a[28], a[59]); SQRADDAC(a[29], a[58]); SQRADDAC(a[30], a[57]); SQRADDAC(a[31], a[56]); SQRADDAC(a[32], a[55]); SQRADDAC(a[33], a[54]); SQRADDAC(a[34], a[53]); SQRADDAC(a[35], a[52]); SQRADDAC(a[36], a[51]); SQRADDAC(a[37], a[50]); SQRADDAC(a[38], a[49]); SQRADDAC(a[39], a[48]); SQRADDAC(a[40], a[47]); SQRADDAC(a[41], a[46]); SQRADDAC(a[42], a[45]); SQRADDAC(a[43], a[44]); SQRADDDB;
4872 SQRADDSC(a[25], a[63]); SQRADDAC(a[26], a[62]); SQRADDAC(a[27], a[61]); SQRADDAC(a[28], a[60]); SQRADDAC(a[29], a[59]); SQRADDAC(a[30], a[58]); SQRADDAC(a[31], a[57]); SQRADDAC(a[32], a[56]); SQRADDAC(a[33], a[55]); SQRADDAC(a[34], a[54]); SQRADDAC(a[35], a[53]); SQRADDAC(a[36], a[52]); SQRADDAC(a[37], a[51]); SQRADDAC(a[38], a[50]); SQRADDAC(a[39], a[49]); SQRADDAC(a[40], a[48]); SQRADDAC(a[41], a[47]); SQRADDAC(a[42], a[46]); SQRADDAC(a[43], a[45]); SQRADDDB; SQRADD(a[44], a[44]);
4877 SQRADDSC(a[26], a[63]); SQRADDAC(a[27], a[62]); SQRADDAC(a[28], a[61]); SQRADDAC(a[29], a[60]); SQRADDAC(a[30], a[59]); SQRADDAC(a[31], a[58]); SQRADDAC(a[32], a[57]); SQRADDAC(a[33], a[56]); SQRADDAC(a[34], a[55]); SQRADDAC(a[35], a[54]); SQRADDAC(a[36], a[53]); SQRADDAC(a[37], a[52]); SQRADDAC(a[38], a[51]); SQRADDAC(a[39], a[50]); SQRADDAC(a[40], a[49]); SQRADDAC(a[41], a[48]); SQRADDAC(a[42], a[47]); SQRADDAC(a[43], a[46]); SQRADDAC(a[44], a[45]); SQRADDDB;
4882 SQRADDSC(a[27], a[63]); SQRADDAC(a[28], a[62]); SQRADDAC(a[29], a[61]); SQRADDAC(a[30], a[60]); SQRADDAC(a[31], a[59]); SQRADDAC(a[32], a[58]); SQRADDAC(a[33], a[57]); SQRADDAC(a[34], a[56]); SQRADDAC(a[35], a[55]); SQRADDAC(a[36], a[54]); SQRADDAC(a[37], a[53]); SQRADDAC(a[38], a[52]); SQRADDAC(a[39], a[51]); SQRADDAC(a[40], a[50]); SQRADDAC(a[41], a[49]); SQRADDAC(a[42], a[48]); SQRADDAC(a[43], a[47]); SQRADDAC(a[44], a[46]); SQRADDDB; SQRADD(a[45], a[45]);
4887 SQRADDSC(a[28], a[63]); SQRADDAC(a[29], a[62]); SQRADDAC(a[30], a[61]); SQRADDAC(a[31], a[60]); SQRADDAC(a[32], a[59]); SQRADDAC(a[33], a[58]); SQRADDAC(a[34], a[57]); SQRADDAC(a[35], a[56]); SQRADDAC(a[36], a[55]); SQRADDAC(a[37], a[54]); SQRADDAC(a[38], a[53]); SQRADDAC(a[39], a[52]); SQRADDAC(a[40], a[51]); SQRADDAC(a[41], a[50]); SQRADDAC(a[42], a[49]); SQRADDAC(a[43], a[48]); SQRADDAC(a[44], a[47]); SQRADDAC(a[45], a[46]); SQRADDDB;
4892 SQRADDSC(a[29], a[63]); SQRADDAC(a[30], a[62]); SQRADDAC(a[31], a[61]); SQRADDAC(a[32], a[60]); SQRADDAC(a[33], a[59]); SQRADDAC(a[34], a[58]); SQRADDAC(a[35], a[57]); SQRADDAC(a[36], a[56]); SQRADDAC(a[37], a[55]); SQRADDAC(a[38], a[54]); SQRADDAC(a[39], a[53]); SQRADDAC(a[40], a[52]); SQRADDAC(a[41], a[51]); SQRADDAC(a[42], a[50]); SQRADDAC(a[43], a[49]); SQRADDAC(a[44], a[48]); SQRADDAC(a[45], a[47]); SQRADDDB; SQRADD(a[46], a[46]);
4897 SQRADDSC(a[30], a[63]); SQRADDAC(a[31], a[62]); SQRADDAC(a[32], a[61]); SQRADDAC(a[33], a[60]); SQRADDAC(a[34], a[59]); SQRADDAC(a[35], a[58]); SQRADDAC(a[36], a[57]); SQRADDAC(a[37], a[56]); SQRADDAC(a[38], a[55]); SQRADDAC(a[39], a[54]); SQRADDAC(a[40], a[53]); SQRADDAC(a[41], a[52]); SQRADDAC(a[42], a[51]); SQRADDAC(a[43], a[50]); SQRADDAC(a[44], a[49]); SQRADDAC(a[45], a[48]); SQRADDAC(a[46], a[47]); SQRADDDB;
4902 SQRADDSC(a[31], a[63]); SQRADDAC(a[32], a[62]); SQRADDAC(a[33], a[61]); SQRADDAC(a[34], a[60]); SQRADDAC(a[35], a[59]); SQRADDAC(a[36], a[58]); SQRADDAC(a[37], a[57]); SQRADDAC(a[38], a[56]); SQRADDAC(a[39], a[55]); SQRADDAC(a[40], a[54]); SQRADDAC(a[41], a[53]); SQRADDAC(a[42], a[52]); SQRADDAC(a[43], a[51]); SQRADDAC(a[44], a[50]); SQRADDAC(a[45], a[49]); SQRADDAC(a[46], a[48]); SQRADDDB; SQRADD(a[47], a[47]);
4907 SQRADDSC(a[32], a[63]); SQRADDAC(a[33], a[62]); SQRADDAC(a[34], a[61]); SQRADDAC(a[35], a[60]); SQRADDAC(a[36], a[59]); SQRADDAC(a[37], a[58]); SQRADDAC(a[38], a[57]); SQRADDAC(a[39], a[56]); SQRADDAC(a[40], a[55]); SQRADDAC(a[41], a[54]); SQRADDAC(a[42], a[53]); SQRADDAC(a[43], a[52]); SQRADDAC(a[44], a[51]); SQRADDAC(a[45], a[50]); SQRADDAC(a[46], a[49]); SQRADDAC(a[47], a[48]); SQRADDDB;
4912 SQRADDSC(a[33], a[63]); SQRADDAC(a[34], a[62]); SQRADDAC(a[35], a[61]); SQRADDAC(a[36], a[60]); SQRADDAC(a[37], a[59]); SQRADDAC(a[38], a[58]); SQRADDAC(a[39], a[57]); SQRADDAC(a[40], a[56]); SQRADDAC(a[41], a[55]); SQRADDAC(a[42], a[54]); SQRADDAC(a[43], a[53]); SQRADDAC(a[44], a[52]); SQRADDAC(a[45], a[51]); SQRADDAC(a[46], a[50]); SQRADDAC(a[47], a[49]); SQRADDDB; SQRADD(a[48], a[48]);
4917 SQRADDSC(a[34], a[63]); SQRADDAC(a[35], a[62]); SQRADDAC(a[36], a[61]); SQRADDAC(a[37], a[60]); SQRADDAC(a[38], a[59]); SQRADDAC(a[39], a[58]); SQRADDAC(a[40], a[57]); SQRADDAC(a[41], a[56]); SQRADDAC(a[42], a[55]); SQRADDAC(a[43], a[54]); SQRADDAC(a[44], a[53]); SQRADDAC(a[45], a[52]); SQRADDAC(a[46], a[51]); SQRADDAC(a[47], a[50]); SQRADDAC(a[48], a[49]); SQRADDDB;
4922 SQRADDSC(a[35], a[63]); SQRADDAC(a[36], a[62]); SQRADDAC(a[37], a[61]); SQRADDAC(a[38], a[60]); SQRADDAC(a[39], a[59]); SQRADDAC(a[40], a[58]); SQRADDAC(a[41], a[57]); SQRADDAC(a[42], a[56]); SQRADDAC(a[43], a[55]); SQRADDAC(a[44], a[54]); SQRADDAC(a[45], a[53]); SQRADDAC(a[46], a[52]); SQRADDAC(a[47], a[51]); SQRADDAC(a[48], a[50]); SQRADDDB; SQRADD(a[49], a[49]);
4927 SQRADDSC(a[36], a[63]); SQRADDAC(a[37], a[62]); SQRADDAC(a[38], a[61]); SQRADDAC(a[39], a[60]); SQRADDAC(a[40], a[59]); SQRADDAC(a[41], a[58]); SQRADDAC(a[42], a[57]); SQRADDAC(a[43], a[56]); SQRADDAC(a[44], a[55]); SQRADDAC(a[45], a[54]); SQRADDAC(a[46], a[53]); SQRADDAC(a[47], a[52]); SQRADDAC(a[48], a[51]); SQRADDAC(a[49], a[50]); SQRADDDB;
4932 SQRADDSC(a[37], a[63]); SQRADDAC(a[38], a[62]); SQRADDAC(a[39], a[61]); SQRADDAC(a[40], a[60]); SQRADDAC(a[41], a[59]); SQRADDAC(a[42], a[58]); SQRADDAC(a[43], a[57]); SQRADDAC(a[44], a[56]); SQRADDAC(a[45], a[55]); SQRADDAC(a[46], a[54]); SQRADDAC(a[47], a[53]); SQRADDAC(a[48], a[52]); SQRADDAC(a[49], a[51]); SQRADDDB; SQRADD(a[50], a[50]);
4933 COMBA_STORE(b[100]);
4937 SQRADDSC(a[38], a[63]); SQRADDAC(a[39], a[62]); SQRADDAC(a[40], a[61]); SQRADDAC(a[41], a[60]); SQRADDAC(a[42], a[59]); SQRADDAC(a[43], a[58]); SQRADDAC(a[44], a[57]); SQRADDAC(a[45], a[56]); SQRADDAC(a[46], a[55]); SQRADDAC(a[47], a[54]); SQRADDAC(a[48], a[53]); SQRADDAC(a[49], a[52]); SQRADDAC(a[50], a[51]); SQRADDDB;
4938 COMBA_STORE(b[101]);
4942 SQRADDSC(a[39], a[63]); SQRADDAC(a[40], a[62]); SQRADDAC(a[41], a[61]); SQRADDAC(a[42], a[60]); SQRADDAC(a[43], a[59]); SQRADDAC(a[44], a[58]); SQRADDAC(a[45], a[57]); SQRADDAC(a[46], a[56]); SQRADDAC(a[47], a[55]); SQRADDAC(a[48], a[54]); SQRADDAC(a[49], a[53]); SQRADDAC(a[50], a[52]); SQRADDDB; SQRADD(a[51], a[51]);
4943 COMBA_STORE(b[102]);
4947 SQRADDSC(a[40], a[63]); SQRADDAC(a[41], a[62]); SQRADDAC(a[42], a[61]); SQRADDAC(a[43], a[60]); SQRADDAC(a[44], a[59]); SQRADDAC(a[45], a[58]); SQRADDAC(a[46], a[57]); SQRADDAC(a[47], a[56]); SQRADDAC(a[48], a[55]); SQRADDAC(a[49], a[54]); SQRADDAC(a[50], a[53]); SQRADDAC(a[51], a[52]); SQRADDDB;
4948 COMBA_STORE(b[103]);
4952 SQRADDSC(a[41], a[63]); SQRADDAC(a[42], a[62]); SQRADDAC(a[43], a[61]); SQRADDAC(a[44], a[60]); SQRADDAC(a[45], a[59]); SQRADDAC(a[46], a[58]); SQRADDAC(a[47], a[57]); SQRADDAC(a[48], a[56]); SQRADDAC(a[49], a[55]); SQRADDAC(a[50], a[54]); SQRADDAC(a[51], a[53]); SQRADDDB; SQRADD(a[52], a[52]);
4953 COMBA_STORE(b[104]);
4957 SQRADDSC(a[42], a[63]); SQRADDAC(a[43], a[62]); SQRADDAC(a[44], a[61]); SQRADDAC(a[45], a[60]); SQRADDAC(a[46], a[59]); SQRADDAC(a[47], a[58]); SQRADDAC(a[48], a[57]); SQRADDAC(a[49], a[56]); SQRADDAC(a[50], a[55]); SQRADDAC(a[51], a[54]); SQRADDAC(a[52], a[53]); SQRADDDB;
4958 COMBA_STORE(b[105]);
4962 SQRADDSC(a[43], a[63]); SQRADDAC(a[44], a[62]); SQRADDAC(a[45], a[61]); SQRADDAC(a[46], a[60]); SQRADDAC(a[47], a[59]); SQRADDAC(a[48], a[58]); SQRADDAC(a[49], a[57]); SQRADDAC(a[50], a[56]); SQRADDAC(a[51], a[55]); SQRADDAC(a[52], a[54]); SQRADDDB; SQRADD(a[53], a[53]);
4963 COMBA_STORE(b[106]);
4967 SQRADDSC(a[44], a[63]); SQRADDAC(a[45], a[62]); SQRADDAC(a[46], a[61]); SQRADDAC(a[47], a[60]); SQRADDAC(a[48], a[59]); SQRADDAC(a[49], a[58]); SQRADDAC(a[50], a[57]); SQRADDAC(a[51], a[56]); SQRADDAC(a[52], a[55]); SQRADDAC(a[53], a[54]); SQRADDDB;
4968 COMBA_STORE(b[107]);
4972 SQRADDSC(a[45], a[63]); SQRADDAC(a[46], a[62]); SQRADDAC(a[47], a[61]); SQRADDAC(a[48], a[60]); SQRADDAC(a[49], a[59]); SQRADDAC(a[50], a[58]); SQRADDAC(a[51], a[57]); SQRADDAC(a[52], a[56]); SQRADDAC(a[53], a[55]); SQRADDDB; SQRADD(a[54], a[54]);
4973 COMBA_STORE(b[108]);
4977 SQRADDSC(a[46], a[63]); SQRADDAC(a[47], a[62]); SQRADDAC(a[48], a[61]); SQRADDAC(a[49], a[60]); SQRADDAC(a[50], a[59]); SQRADDAC(a[51], a[58]); SQRADDAC(a[52], a[57]); SQRADDAC(a[53], a[56]); SQRADDAC(a[54], a[55]); SQRADDDB;
4978 COMBA_STORE(b[109]);
4982 SQRADDSC(a[47], a[63]); SQRADDAC(a[48], a[62]); SQRADDAC(a[49], a[61]); SQRADDAC(a[50], a[60]); SQRADDAC(a[51], a[59]); SQRADDAC(a[52], a[58]); SQRADDAC(a[53], a[57]); SQRADDAC(a[54], a[56]); SQRADDDB; SQRADD(a[55], a[55]);
4983 COMBA_STORE(b[110]);
4987 SQRADDSC(a[48], a[63]); SQRADDAC(a[49], a[62]); SQRADDAC(a[50], a[61]); SQRADDAC(a[51], a[60]); SQRADDAC(a[52], a[59]); SQRADDAC(a[53], a[58]); SQRADDAC(a[54], a[57]); SQRADDAC(a[55], a[56]); SQRADDDB;
4988 COMBA_STORE(b[111]);
4992 SQRADDSC(a[49], a[63]); SQRADDAC(a[50], a[62]); SQRADDAC(a[51], a[61]); SQRADDAC(a[52], a[60]); SQRADDAC(a[53], a[59]); SQRADDAC(a[54], a[58]); SQRADDAC(a[55], a[57]); SQRADDDB; SQRADD(a[56], a[56]);
4993 COMBA_STORE(b[112]);
4997 SQRADDSC(a[50], a[63]); SQRADDAC(a[51], a[62]); SQRADDAC(a[52], a[61]); SQRADDAC(a[53], a[60]); SQRADDAC(a[54], a[59]); SQRADDAC(a[55], a[58]); SQRADDAC(a[56], a[57]); SQRADDDB;
4998 COMBA_STORE(b[113]);
5002 SQRADDSC(a[51], a[63]); SQRADDAC(a[52], a[62]); SQRADDAC(a[53], a[61]); SQRADDAC(a[54], a[60]); SQRADDAC(a[55], a[59]); SQRADDAC(a[56], a[58]); SQRADDDB; SQRADD(a[57], a[57]);
5003 COMBA_STORE(b[114]);
5007 SQRADDSC(a[52], a[63]); SQRADDAC(a[53], a[62]); SQRADDAC(a[54], a[61]); SQRADDAC(a[55], a[60]); SQRADDAC(a[56], a[59]); SQRADDAC(a[57], a[58]); SQRADDDB;
5008 COMBA_STORE(b[115]);
5012 SQRADDSC(a[53], a[63]); SQRADDAC(a[54], a[62]); SQRADDAC(a[55], a[61]); SQRADDAC(a[56], a[60]); SQRADDAC(a[57], a[59]); SQRADDDB; SQRADD(a[58], a[58]);
5013 COMBA_STORE(b[116]);
5017 SQRADDSC(a[54], a[63]); SQRADDAC(a[55], a[62]); SQRADDAC(a[56], a[61]); SQRADDAC(a[57], a[60]); SQRADDAC(a[58], a[59]); SQRADDDB;
5018 COMBA_STORE(b[117]);
5022 SQRADDSC(a[55], a[63]); SQRADDAC(a[56], a[62]); SQRADDAC(a[57], a[61]); SQRADDAC(a[58], a[60]); SQRADDDB; SQRADD(a[59], a[59]);
5023 COMBA_STORE(b[118]);
5027 SQRADDSC(a[56], a[63]); SQRADDAC(a[57], a[62]); SQRADDAC(a[58], a[61]); SQRADDAC(a[59], a[60]); SQRADDDB;
5028 COMBA_STORE(b[119]);
5032 SQRADDSC(a[57], a[63]); SQRADDAC(a[58], a[62]); SQRADDAC(a[59], a[61]); SQRADDDB; SQRADD(a[60], a[60]);
5033 COMBA_STORE(b[120]);
5037 SQRADDSC(a[58], a[63]); SQRADDAC(a[59], a[62]); SQRADDAC(a[60], a[61]); SQRADDDB;
5038 COMBA_STORE(b[121]);
5042 SQRADD2(a[59], a[63]); SQRADD2(a[60], a[62]); SQRADD(a[61], a[61]);
5043 COMBA_STORE(b[122]);
5047 SQRADD2(a[60], a[63]); SQRADD2(a[61], a[62]);
5048 COMBA_STORE(b[123]);
5052 SQRADD2(a[61], a[63]); SQRADD(a[62], a[62]);
5053 COMBA_STORE(b[124]);
5057 SQRADD2(a[62], a[63]);
5058 COMBA_STORE(b[125]);
5062 SQRADD(a[63], a[63]);
5063 COMBA_STORE(b[126]);
5064 COMBA_STORE2(b[127]);
5069 memcpy(B->dp, b, 128 * sizeof(fp_digit));
5076 /* End: fp_sqr_comba.c */
5078 /* Start: fp_sqr_comba_generic.c */
5079 /* generic comba squarer */
5080 void fp_sqr_comba(fp_int *A, fp_int *B)
5083 fp_digit c0, c1, c2;
5086 /* get size of output and trim */
5087 pa = A->used + A->used;
5088 if (pa >= FP_SIZE) {
5092 /* number of output digits to produce */
5104 for (ix = 0; ix < pa; ix++) {
5106 fp_digit *tmpy, *tmpx;
5108 /* get offsets into the two bignums */
5109 ty = MIN(A->used-1, ix);
5112 /* setup temp aliases */
5116 /* this is the number of times the loop will iterrate, essentially its
5117 while (tx++ < a->used && ty-- >= 0) { ... }
5119 iy = MIN(A->used-tx, ty+1);
5121 /* now for squaring tx can never equal ty
5122 * we halve the distance since they approach at a rate of 2x
5123 * and we have to round because odd cases need to be executed
5125 iy = MIN(iy, (ty-tx+1)>>1);
5127 /* forward carries */
5131 for (iz = 0; iz < iy; iz++) {
5132 SQRADD2(*tmpx++, *tmpy--);
5135 /* even columns have the square term in them */
5137 SQRADD(A->dp[ix>>1], A->dp[ix>>1]);
5141 COMBA_STORE(dst->dp[ix]);
5143 COMBA_STORE2(dst->dp[ix]);
5155 /* End: fp_sqr_comba_generic.c */
5157 /* Start: fp_sqrmod.c */
5158 /* TomsFastMath, a fast ISO C bignum library.
5160 * This project is meant to fill in where LibTomMath
5161 * falls short. That is speed ;-)
5163 * This project is public domain and free for all purposes.
5165 * Tom St Denis, tomstdenis@iahu.ca
5169 /* c = a * a (mod b) */
5170 int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c)
5175 return fp_mod(&tmp, b, c);
5178 /* End: fp_sqrmod.c */
5180 /* Start: fp_sub.c */
5181 /* TomsFastMath, a fast ISO C bignum library.
5183 * This project is meant to fill in where LibTomMath
5184 * falls short. That is speed ;-)
5186 * This project is public domain and free for all purposes.
5188 * Tom St Denis, tomstdenis@iahu.ca
5193 void fp_sub(fp_int *a, fp_int *b, fp_int *c)
5201 /* subtract a negative from a positive, OR */
5202 /* subtract a positive from a negative. */
5203 /* In either case, ADD their magnitudes, */
5204 /* and use the sign of the first number. */
5208 /* subtract a positive from a positive, OR */
5209 /* subtract a negative from a negative. */
5210 /* First, take the difference between their */
5211 /* magnitudes, then... */
5212 if (fp_cmp_mag (a, b) != FP_LT) {
5213 /* Copy the sign from the first */
5215 /* The first has a larger or equal magnitude */
5218 /* The result has the *opposite* sign from */
5219 /* the first number. */
5220 c->sign = (sa == FP_ZPOS) ? FP_NEG : FP_ZPOS;
5221 /* The second has a larger magnitude */
5230 /* Start: fp_sub_d.c */
5231 /* TomsFastMath, a fast ISO C bignum library.
5233 * This project is meant to fill in where LibTomMath
5234 * falls short. That is speed ;-)
5236 * This project is public domain and free for all purposes.
5238 * Tom St Denis, tomstdenis@iahu.ca
5243 void fp_sub_d(fp_int *a, fp_digit b, fp_int *c)
5250 /* End: fp_sub_d.c */
5252 /* Start: fp_submod.c */
5253 /* TomsFastMath, a fast ISO C bignum library.
5255 * This project is meant to fill in where LibTomMath
5256 * falls short. That is speed ;-)
5258 * This project is public domain and free for all purposes.
5260 * Tom St Denis, tomstdenis@iahu.ca
5264 /* d = a - b (mod c) */
5265 int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
5270 return fp_mod(&tmp, c, d);
5274 /* End: fp_submod.c */
5276 /* Start: fp_to_signed_bin.c */
5277 /* TomsFastMath, a fast ISO C bignum library.
5279 * This project is meant to fill in where LibTomMath
5280 * falls short. That is speed ;-)
5282 * This project is public domain and free for all purposes.
5284 * Tom St Denis, tomstdenis@iahu.ca
5288 void fp_to_signed_bin(fp_int *a, unsigned char *b)
5290 fp_to_unsigned_bin (a, b + 1);
5291 b[0] = (unsigned char) ((a->sign == FP_ZPOS) ? 0 : 1);
5294 /* End: fp_to_signed_bin.c */
5296 /* Start: fp_to_unsigned_bin.c */
5297 /* TomsFastMath, a fast ISO C bignum library.
5299 * This project is meant to fill in where LibTomMath
5300 * falls short. That is speed ;-)
5302 * This project is public domain and free for all purposes.
5304 * Tom St Denis, tomstdenis@iahu.ca
5308 void fp_to_unsigned_bin(fp_int *a, unsigned char *b)
5313 fp_init_copy(&t, a);
5316 while (fp_iszero (&t) == FP_NO) {
5317 b[x++] = (unsigned char) (t.dp[0] & 255);
5318 fp_div_2d (&t, 8, &t, NULL);
5323 /* End: fp_to_unsigned_bin.c */
5325 /* Start: fp_toradix.c */
5326 /* TomsFastMath, a fast ISO C bignum library.
5328 * This project is meant to fill in where LibTomMath
5329 * falls short. That is speed ;-)
5331 * This project is public domain and free for all purposes.
5333 * Tom St Denis, tomstdenis@iahu.ca
5337 int fp_toradix(fp_int *a, char *str, int radix)
5344 /* check range of the radix */
5345 if (radix < 2 || radix > 64) {
5349 /* quick out if its zero */
5350 if (fp_iszero(a) == 1) {
5356 fp_init_copy(&t, a);
5358 /* if it is negative output a - */
5359 if (t.sign == FP_NEG) {
5366 while (fp_iszero (&t) == FP_NO) {
5367 fp_div_d (&t, (fp_digit) radix, &t, &d);
5368 *str++ = fp_s_rmap[d];
5372 /* reverse the digits of the string. In this case _s points
5373 * to the first digit [exluding the sign] of the number]
5375 bn_reverse ((unsigned char *)_s, digs);
5377 /* append a NULL so the string is properly terminated */
5382 /* End: fp_toradix.c */
5384 /* Start: fp_unsigned_bin_size.c */
5385 /* TomsFastMath, a fast ISO C bignum library.
5387 * This project is meant to fill in where LibTomMath
5388 * falls short. That is speed ;-)
5390 * This project is public domain and free for all purposes.
5392 * Tom St Denis, tomstdenis@iahu.ca
5396 int fp_unsigned_bin_size(fp_int *a)
5398 int size = fp_count_bits (a);
5399 return (size / 8 + ((size & 7) != 0 ? 1 : 0));
5402 /* End: fp_unsigned_bin_size.c */
5404 /* Start: s_fp_add.c */
5405 /* TomsFastMath, a fast ISO C bignum library.
5407 * This project is meant to fill in where LibTomMath
5408 * falls short. That is speed ;-)
5410 * This project is public domain and free for all purposes.
5412 * Tom St Denis, tomstdenis@iahu.ca
5416 /* unsigned addition */
5417 void s_fp_add(fp_int *a, fp_int *b, fp_int *c)
5422 y = MAX(a->used, b->used);
5427 for (x = 0; x < y; x++) {
5428 t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]);
5429 c->dp[x] = (fp_digit)t;
5432 if (t != 0 && x != FP_SIZE) {
5433 c->dp[c->used++] = (fp_digit)t;
5437 for (; x < oldused; x++) {
5443 /* End: s_fp_add.c */
5445 /* Start: s_fp_sub.c */
5446 /* TomsFastMath, a fast ISO C bignum library.
5448 * This project is meant to fill in where LibTomMath
5449 * falls short. That is speed ;-)
5451 * This project is public domain and free for all purposes.
5453 * Tom St Denis, tomstdenis@iahu.ca
5457 /* unsigned subtraction ||a|| >= ||b|| ALWAYS! */
5458 void s_fp_sub(fp_int *a, fp_int *b, fp_int *c)
5466 for (x = 0; x < a->used; x++) {
5467 t = ((fp_word)a->dp[x]) - (((fp_word)b->dp[x]) + t);
5468 c->dp[x] = (fp_digit)t;
5469 t = (t >> DIGIT_BIT) & 1;
5472 for (; x < oldused; x++) {
5478 /* End: s_fp_sub.c */