//------------------------------------------------------------------------------------- static int get_auth_ra_key(fp_int *n, fp_int *e, fp_int *d) { int nRet = 1; if(!n || !e || !d) return nRet; if(pauth_ra->status != 0) return nRet; // unsigned char szTxtN[] = {0xB9,0x14,0xF5,0x2B,0x27,0x16,0x97,0x8A,0x19,0x54,0x8C,0x38,0xB9,0xA5,0xA9,0xA1,0x6C,0x8A,0x3A,0x2A,0x8D,0x1D,0x10,0x44,0x8B,0x53,0x8A,0xA4,0xE4,0x49,0x82,0xA1,0xD5,0x1D,0x3B,0x0A,0x2B,0xA0,0x48,0x0A,0x9D,0xBA,0xF7,0x79,0xC9,0xF2,0x17,0xE2,0x6B,0x32,0x8F,0xC9,0xED,0x13,0xA8,0x38,0xD1,0x27,0x2A,0xBD,0xE1,0xE8,0x8C,0xAF,0x0A,0x15,0x58,0xF7,0xF5,0x8D,0xAA,0x85,0xBB,0xEB,0x51,0x74,0x66,0x8C,0x00,0xB4,0x1E,0x97,0x14,0xD6,0x1B,0x3A,0x3E,0x54,0xED,0x8C,0x82,0xDA,0x3E,0x06,0x68,0xFB,0x51,0x0C,0x72,0xF6,0xE3,0x0F,0x09,0xF2,0xB3,0xFF,0xD7,0xF2,0xF5,0x5D,0x06,0x58,0xFC,0x9D,0xB3,0x53,0x5F,0x45,0x2F,0x22,0x17,0x1E,0x4A,0x4F,0x0A,0xBF,0x04,0x73}; // unsigned char szTxtE[] = {0x4B,0x37,0x01}; // unsigned char szTxtD[] = {0xCF,0x8D,0xF9,0xC9,0x57,0x53,0x4D,0xD7,0x36,0xFD,0x27,0x3E,0xA9,0x3A,0x76,0xE8,0xC1,0x50,0x7F,0x95,0x65,0xF8,0x99,0x14,0xD7,0x6C,0x3F,0x1A,0x9D,0x50,0xD3,0x95,0x7C,0xC8,0xFE,0xE3,0x04,0x85,0xF9,0x5A,0xCF,0x48,0x42,0x15,0x83,0x0E,0xE2,0xB6,0xC6,0xC8,0x4F,0xB8,0xA3,0x9B,0xF2,0xAB,0x95,0x20,0xE0,0x0D,0x10,0x16,0x6D,0xFB,0x95,0x38,0x15,0x24,0x82,0x15,0xEC,0x4F,0xF1,0xCF,0xFA,0x76,0x83,0x74,0x8F,0x0B,0xA4,0x79,0x45,0xEB,0x61,0xA8,0xD5,0x26,0x60,0x3D,0x6C,0x8D,0x46,0x9A,0xDE,0xFB,0x5C,0x26,0x77,0x5F,0x2A,0xCD,0x97,0xD6,0x13,0x90,0x72,0xAF,0x4E,0x6F,0x54,0x63,0xFE,0xCB,0xF6,0x69,0x97,0xB1,0x5C,0xA3,0xD6,0x7A,0xDA,0xDF,0x74,0xC9,0x35,0x4F}; fp_init(n); fp_init(e); fp_init(d); /*memcpy(n->dp,szTxtN,sizeof(szTxtN)); memcpy(e->dp,szTxtE,sizeof(szTxtE)); memcpy(d->dp,szTxtD,sizeof(szTxtD));*/ memcpy(n->dp, pauth_ra->n, 128); memcpy(e->dp,pauth_ra->e,5); memcpy(d->dp, pauth_ra->d, 128); n->used=FP_SIZE; fp_clamp(n); e->used=FP_SIZE; fp_clamp(e); d->used=FP_SIZE; fp_clamp(d); nRet = 0; return nRet; }
//==================================================================== // interface APIs //==================================================================== static int get_secu_ra_key(fp_int *n, fp_int *e, fp_int *d) { int nRet = 1; if(!n || !e || !d) return nRet; if(psecu_ra->status != 0) return nRet; fp_init(n); fp_init(e); fp_init(d); /*memcpy(n->dp,szTxtN,128); memcpy(e->dp,szTxtE,128); memcpy(d->dp,szTxtD,128);*/ memcpy(n->dp, psecu_ra->n, 128); memcpy(e->dp,psecu_ra->e,5); memcpy(d->dp, psecu_ra->d, 128); n->used=FP_SIZE; fp_clamp(n); e->used=FP_SIZE; fp_clamp(e); d->used=FP_SIZE; fp_clamp(d); nRet = 0; return nRet; }
//RSA key : psudo code for demo //0 is success, 1 for fail static int get_rsa_key(fp_int *n,fp_int *e,fp_int*d) { //here the long number is little //to replace N,E,D... unsigned char szTxtN[] = {0xB9,0x14,0xF5,0x2B,0x27,0x16,0x97,0x8A,0x19,0x54,0x8C,0x38,0xB9,0xA5,0xA9,0xA1,0x6C,0x8A,0x3A,0x2A,0x8D,0x1D,0x10,0x44,0x8B,0x53,0x8A,0xA4,0xE4,0x49,0x82,0xA1,0xD5,0x1D,0x3B,0x0A,0x2B,0xA0,0x48,0x0A,0x9D,0xBA,0xF7,0x79,0xC9,0xF2,0x17,0xE2,0x6B,0x32,0x8F,0xC9,0xED,0x13,0xA8,0x38,0xD1,0x27,0x2A,0xBD,0xE1,0xE8,0x8C,0xAF,0x0A,0x15,0x58,0xF7,0xF5,0x8D,0xAA,0x85,0xBB,0xEB,0x51,0x74,0x66,0x8C,0x00,0xB4,0x1E,0x97,0x14,0xD6,0x1B,0x3A,0x3E,0x54,0xED,0x8C,0x82,0xDA,0x3E,0x06,0x68,0xFB,0x51,0x0C,0x72,0xF6,0xE3,0x0F,0x09,0xF2,0xB3,0xFF,0xD7,0xF2,0xF5,0x5D,0x06,0x58,0xFC,0x9D,0xB3,0x53,0x5F,0x45,0x2F,0x22,0x17,0x1E,0x4A,0x4F,0x0A,0xBF,0x04,0x73}; unsigned char szTxtE[] = {0x4B,0x37,0x01}; unsigned char szTxtD[] = {0xCF,0x8D,0xF9,0xC9,0x57,0x53,0x4D,0xD7,0x36,0xFD,0x27,0x3E,0xA9,0x3A,0x76,0xE8,0xC1,0x50,0x7F,0x95,0x65,0xF8,0x99,0x14,0xD7,0x6C,0x3F,0x1A,0x9D,0x50,0xD3,0x95,0x7C,0xC8,0xFE,0xE3,0x04,0x85,0xF9,0x5A,0xCF,0x48,0x42,0x15,0x83,0x0E,0xE2,0xB6,0xC6,0xC8,0x4F,0xB8,0xA3,0x9B,0xF2,0xAB,0x95,0x20,0xE0,0x0D,0x10,0x16,0x6D,0xFB,0x95,0x38,0x15,0x24,0x82,0x15,0xEC,0x4F,0xF1,0xCF,0xFA,0x76,0x83,0x74,0x8F,0x0B,0xA4,0x79,0x45,0xEB,0x61,0xA8,0xD5,0x26,0x60,0x3D,0x6C,0x8D,0x46,0x9A,0xDE,0xFB,0x5C,0x26,0x77,0x5F,0x2A,0xCD,0x97,0xD6,0x13,0x90,0x72,0xAF,0x4E,0x6F,0x54,0x63,0xFE,0xCB,0xF6,0x69,0x97,0xB1,0x5C,0xA3,0xD6,0x7A,0xDA,0xDF,0x74,0xC9,0x35,0x4F}; void* n_address = (void*)(0x49000000 + 16 * 1024 + 384 + 256); void* e_address = n_address + 128; memcpy((void*)szTxtN, n_address, 128); memcpy((void*)szTxtE, e_address, 3); int nRet = 1; if(!n || !e || !d) return nRet; fp_init(n); fp_init(e); fp_init(d); memcpy(n->dp,szTxtN,sizeof(szTxtN)); memcpy(e->dp,szTxtE,sizeof(szTxtE)); memcpy(d->dp,szTxtD,sizeof(szTxtD)); n->used=FP_SIZE; fp_clamp(n); e->used=FP_SIZE; fp_clamp(e); d->used=FP_SIZE; fp_clamp(d); nRet = 0; return nRet; }
void fp_mul_comba3(fp_int *A, fp_int *B, fp_int *C) { fp_digit c0, c1, c2, at[6]; memcpy(at, A->dp, 3 * sizeof(fp_digit)); memcpy(at+3, B->dp, 3 * sizeof(fp_digit)); COMBA_START; COMBA_CLEAR; /* 0 */ MULADD(at[0], at[3]); COMBA_STORE(C->dp[0]); /* 1 */ COMBA_FORWARD; MULADD(at[0], at[4]); MULADD(at[1], at[3]); COMBA_STORE(C->dp[1]); /* 2 */ COMBA_FORWARD; MULADD(at[0], at[5]); MULADD(at[1], at[4]); MULADD(at[2], at[3]); COMBA_STORE(C->dp[2]); /* 3 */ COMBA_FORWARD; MULADD(at[1], at[5]); MULADD(at[2], at[4]); COMBA_STORE(C->dp[3]); /* 4 */ COMBA_FORWARD; MULADD(at[2], at[5]); COMBA_STORE(C->dp[4]); COMBA_STORE2(C->dp[5]); C->used = 6; C->sign = A->sign ^ B->sign; fp_clamp(C); COMBA_FINI; }
/* unsigned addition */ void s_fp_add(fp_int *a, fp_int *b, fp_int *c) { int x, y, oldused; register fp_word t; y = MAX(a->used, b->used); oldused = c->used; c->used = y; t = 0; for (x = 0; x < y; x++) { t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]); c->dp[x] = (fp_digit)t; t >>= DIGIT_BIT; } if (t != 0 && x < FP_SIZE) { c->dp[c->used++] = (fp_digit)t; ++x; } c->used = x; for (; x < oldused; x++) { c->dp[x] = 0; } fp_clamp(c); }
/* c = a mod 2**d */ void fp_mod_2d(fp_int *a, int b, fp_int *c) { int x; /* zero if count less than or equal to zero */ if (b <= 0) { fp_zero(c); return; } /* get copy of input */ fp_copy(a, c); /* if 2**d is larger than we just return */ if (b >= (DIGIT_BIT * a->used)) { return; } /* zero digits above the last digit of the modulus */ for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { c->dp[x] = 0; } /* clear the digit that is not completely outside/inside the modulus */ c->dp[b / DIGIT_BIT] &= ~((fp_digit)0) >> (DIGIT_BIT - b); fp_clamp (c); }
void fp_mul_comba6(fp_int *A, fp_int *B, fp_int *C) { fp_digit c0, c1, c2, at[12]; memcpy(at, A->dp, 6 * sizeof(fp_digit)); memcpy(at+6, B->dp, 6 * sizeof(fp_digit)); COMBA_START; COMBA_CLEAR; /* 0 */ MULADD(at[0], at[6]); COMBA_STORE(C->dp[0]); /* 1 */ COMBA_FORWARD; MULADD(at[0], at[7]); MULADD(at[1], at[6]); COMBA_STORE(C->dp[1]); /* 2 */ COMBA_FORWARD; MULADD(at[0], at[8]); MULADD(at[1], at[7]); MULADD(at[2], at[6]); COMBA_STORE(C->dp[2]); /* 3 */ COMBA_FORWARD; MULADD(at[0], at[9]); MULADD(at[1], at[8]); MULADD(at[2], at[7]); MULADD(at[3], at[6]); COMBA_STORE(C->dp[3]); /* 4 */ COMBA_FORWARD; MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]); MULADD(at[3], at[7]); MULADD(at[4], at[6]); COMBA_STORE(C->dp[4]); /* 5 */ COMBA_FORWARD; MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]); MULADD(at[4], at[7]); MULADD(at[5], at[6]); COMBA_STORE(C->dp[5]); /* 6 */ COMBA_FORWARD; MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]); MULADD(at[5], at[7]); COMBA_STORE(C->dp[6]); /* 7 */ COMBA_FORWARD; MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]); COMBA_STORE(C->dp[7]); /* 8 */ COMBA_FORWARD; MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); COMBA_STORE(C->dp[8]); /* 9 */ COMBA_FORWARD; MULADD(at[4], at[11]); MULADD(at[5], at[10]); COMBA_STORE(C->dp[9]); /* 10 */ COMBA_FORWARD; MULADD(at[5], at[11]); COMBA_STORE(C->dp[10]); COMBA_STORE2(C->dp[11]); C->used = 12; C->sign = A->sign ^ B->sign; fp_clamp(C); COMBA_FINI; }
/* generic PxQ multiplier */ void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) { int ix, iy, iz, tx, ty, pa; fp_digit c0, c1, c2, *tmpx, *tmpy; fp_int tmp, *dst; COMBA_START; COMBA_CLEAR; /* get size of output and trim */ pa = A->used + B->used; if (pa >= FP_SIZE) { pa = FP_SIZE-1; } if (A == C || B == C) { fp_zero(&tmp); dst = &tmp; } else { fp_zero(C); dst = C; } for (ix = 0; ix < pa; ix++) { /* get offsets into the two bignums */ ty = MIN(ix, B->used-1); tx = ix - ty; /* setup temp aliases */ tmpx = A->dp + tx; tmpy = B->dp + ty; /* this is the number of times the loop will iterrate, essentially its while (tx++ < a->used && ty-- >= 0) { ... } */ iy = MIN(A->used-tx, ty+1); /* execute loop */ COMBA_FORWARD; for (iz = 0; iz < iy; ++iz) { MULADD(*tmpx++, *tmpy--); } /* store term */ COMBA_STORE(dst->dp[ix]); } COMBA_FINI; dst->used = pa; dst->sign = A->sign ^ B->sign; fp_clamp(dst); fp_copy(dst, C); }
void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c) { /* zero the int */ fp_zero (a); /* If we know the endianness of this architecture, and we're using 32-bit fp_digits, we can optimize this */ #if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(FP_64BIT) /* But not for both simultaneously */ #if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG) #error Both ENDIAN_LITTLE and ENDIAN_BIG defined. #endif { unsigned char *pd = (unsigned char *)a->dp; if ((unsigned)c > (FP_SIZE * sizeof(fp_digit))) { int excess = c - (FP_SIZE * sizeof(fp_digit)); c -= excess; b += excess; } a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit); /* read the bytes in */ #ifdef ENDIAN_BIG { /* Use Duff's device to unroll the loop. */ int idx = (c - 1) & ~3; switch (c % 4) { case 0: do { pd[idx+0] = *b++; case 3: pd[idx+1] = *b++; case 2: pd[idx+2] = *b++; case 1: pd[idx+3] = *b++; idx -= 4; } while ((c -= 4) > 0); } } #else for (c -= 1; c >= 0; c -= 1) { pd[c] = *b++; } #endif } #else /* read the bytes in */ for (; c > 0; c--) { fp_mul_2d (a, 8, a); a->dp[0] |= *b++; a->used += 1; } #endif fp_clamp (a); }
/*m6_rsa_dec_pub_apage * index: m6 chip index * src : buff size fixed 128byte * out : buff size fixed 124byte * */ static int m6_rsa_dec_pub_apage(int index,aml_intx *n,aml_intx *e,unsigned char *src,unsigned char *out) { aml_intx c,m; t_func_v3 fp_00 = (t_func_v3)m6_g_action[index][0]; t_func_v3 fp_02 = (t_func_v3)m6_g_action[index][2]; func_rsa_exp fp_03 = (func_rsa_exp)m6_g_action[index][3]; fp_00((int)&c,0,sizeof(aml_intx)); fp_00((int)&m,0,sizeof(aml_intx)); fp_02((int)&c.dp[0],(int)src,128); c.used=32; fp_clamp(&c); fp_03(&c,e,n,&m); fp_02((int)out,(int)&m.dp[0],124); return 0; }
void fp_sqr_comba3(fp_int *A, fp_int *B) { fp_digit *a, b[6], c0, c1, c2, sc0, sc1, sc2; #ifdef TFM_ISO fp_word tt; #endif a = A->dp; COMBA_START; /* clear carries */ CLEAR_CARRY; /* output 0 */ SQRADD(a[0],a[0]); COMBA_STORE(b[0]); /* output 1 */ CARRY_FORWARD; SQRADD2(a[0], a[1]); COMBA_STORE(b[1]); /* output 2 */ CARRY_FORWARD; SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); COMBA_STORE(b[2]); /* output 3 */ CARRY_FORWARD; SQRADD2(a[1], a[2]); COMBA_STORE(b[3]); /* output 4 */ CARRY_FORWARD; SQRADD(a[2], a[2]); COMBA_STORE(b[4]); COMBA_STORE2(b[5]); COMBA_FINI; B->used = 6; B->sign = FP_ZPOS; memcpy(B->dp, b, 6 * sizeof(fp_digit)); memset(B->dp + 6, 0, (FP_SIZE - 6) * sizeof(fp_digit)); fp_clamp(B); }
/* c = a * b */ void fp_mul_d(fp_int *a, fp_digit b, fp_int *c) { fp_word w; int x, oldused; oldused = c->used; c->used = a->used; c->sign = a->sign; w = 0; for (x = 0; x < a->used; x++) { w = ((fp_word)a->dp[x]) * ((fp_word)b) + w; c->dp[x] = (fp_digit)w; w = w >> DIGIT_BIT; } if (w != 0 && (a->used != FP_SIZE)) { c->dp[c->used++] = w; ++x; } for (; x < oldused; x++) { c->dp[x] = 0; } fp_clamp(c); }
void fp_lshd(fp_int *a, int x) { int y; /* move up and truncate as required */ y = MIN(a->used + x - 1, (int)(FP_SIZE-1)); /* store new size */ a->used = y + 1; /* move digits */ for (; y >= x; y--) { a->dp[y] = a->dp[y-x]; } /* zero lower digits */ for (; y >= 0; y--) { a->dp[y] = 0; } /* clamp digits */ fp_clamp(a); }
/* b = a/2 */ void fp_div_2(fp_int * a, fp_int * b) { int x, oldused; oldused = b->used; b->used = a->used; { register fp_digit r, rr, *tmpa, *tmpb; /* source alias */ tmpa = a->dp + b->used - 1; /* dest alias */ tmpb = b->dp + b->used - 1; /* carry */ r = 0; for (x = b->used - 1; x >= 0; x--) { /* get the carry for the next iteration */ rr = *tmpa & 1; /* shift the current digit, add in carry and store */ *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); /* forward carry to next iteration */ r = rr; } /* zero excess digits */ tmpb = b->dp + b->used; for (x = b->used; x < oldused; x++) { *tmpb++ = 0; } } b->sign = a->sign; fp_clamp (b); }
void fp_rshd(fp_int *a, int x) { int y; /* too many digits just zero and return */ if (x >= a->used) { fp_zero(a); return; } /* shift */ for (y = 0; y < a->used - x; y++) { a->dp[y] = a->dp[y+x]; } /* zero rest */ for (; y < a->used; y++) { a->dp[y] = 0; } /* decrement count */ a->used -= x; fp_clamp(a); }
int do_rsa_enc_dec(char *pSRC, int nDataLen,char *pOUT,int *pOUTLen,int procedure) { int in_size = nDataLen; int nret = 1; if ( NULL == pSRC || NULL == pOUT ) return nret; //check nSRCLen for dec & enc //... unsigned char *pSRCBuff = (unsigned char *)pSRC; unsigned char *pOUTBuff = (unsigned char *)pOUT; //clear output buffer?? memset(pOUTBuff,0,*pOUTLen); *pOUTLen = 0; //prepare key fp_int key[3]; memset(&key[0],0,sizeof(key)); //get key from efuse if(get_rsa_key(&key[0],&key[1],&key[2])) return nret; int nlen; fp_int c,m; fp_int* k,* t; //get key length //for RSA1024 : 1028bit -> 128 bytes //dec-i_len : 128 dec-o_len:127 //enc-i_len : 127 dec-o_len:128 uint32_t bits=fp_count_bits(&key[0]); uint32_t o_len,i_len; //dec i_len=(bits+7)>>3; o_len=i_len-1; //pub key k=&key[1]; switch(procedure & RSA_ENC_DEC_MASK) { case ENC_WITH_PRIV:o_len=i_len;--i_len;;k=&key[2];break; case DEC_WITH_PUB:break; case ENC_WITH_PUB:o_len=i_len;--i_len;break; case DEC_WITH_PRIV:k=&key[2];break; default: printf("Internal error! Not support this enc-dec mode %d\n",procedure);return nret; break; } //buffer process // aml_buffer_proc_before(pSRCBuff,nDataLen,i_len,procedure); for(nlen=0;nlen<in_size;nlen+=i_len) { fp_init(&c); fp_init(&m); memcpy(c.dp,pSRCBuff,i_len); pSRCBuff += i_len; c.used=FP_SIZE; fp_clamp(&c); fp_exptmod(&c,k,&key[0],&m); memcpy(pOUTBuff+*pOUTLen,m.dp,o_len); *pOUTLen += o_len; } //buffer process // aml_buffer_proc_after(pOUTBuff,pOUTLen,o_len,procedure); nret = 0; return nret; }
void fp_mul_comba17(fp_int *A, fp_int *B, fp_int *C) { fp_digit c0, c1, c2, at[34]; memcpy(at, A->dp, 17 * sizeof(fp_digit)); memcpy(at+17, B->dp, 17 * sizeof(fp_digit)); COMBA_START; COMBA_CLEAR; /* 0 */ MULADD(at[0], at[17]); COMBA_STORE(C->dp[0]); /* 1 */ COMBA_FORWARD; MULADD(at[0], at[18]); MULADD(at[1], at[17]); COMBA_STORE(C->dp[1]); /* 2 */ COMBA_FORWARD; MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); COMBA_STORE(C->dp[2]); /* 3 */ COMBA_FORWARD; MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); COMBA_STORE(C->dp[3]); /* 4 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[4]); /* 5 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[5]); /* 6 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[6]); /* 7 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[7]); /* 8 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[8]); /* 9 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[9]); /* 10 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[10]); /* 11 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[11]); /* 12 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[12]); /* 13 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[13]); /* 14 */ COMBA_FORWARD; 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]); COMBA_STORE(C->dp[14]); /* 15 */ COMBA_FORWARD; MULADD(at[0], at[32]); 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]); COMBA_STORE(C->dp[15]); /* 16 */ COMBA_FORWARD; MULADD(at[0], at[33]); MULADD(at[1], at[32]); 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]); MULADD(at[16], at[17]); COMBA_STORE(C->dp[16]); /* 17 */ COMBA_FORWARD; MULADD(at[1], at[33]); MULADD(at[2], at[32]); 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]); MULADD(at[16], at[18]); COMBA_STORE(C->dp[17]); /* 18 */ COMBA_FORWARD; MULADD(at[2], at[33]); MULADD(at[3], at[32]); 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]); MULADD(at[16], at[19]); COMBA_STORE(C->dp[18]); /* 19 */ COMBA_FORWARD; MULADD(at[3], at[33]); MULADD(at[4], at[32]); 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]); MULADD(at[16], at[20]); COMBA_STORE(C->dp[19]); /* 20 */ COMBA_FORWARD; MULADD(at[4], at[33]); MULADD(at[5], at[32]); 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]); MULADD(at[16], at[21]); COMBA_STORE(C->dp[20]); /* 21 */ COMBA_FORWARD; MULADD(at[5], at[33]); MULADD(at[6], at[32]); 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]); MULADD(at[16], at[22]); COMBA_STORE(C->dp[21]); /* 22 */ COMBA_FORWARD; MULADD(at[6], at[33]); MULADD(at[7], at[32]); 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]); MULADD(at[16], at[23]); COMBA_STORE(C->dp[22]); /* 23 */ COMBA_FORWARD; MULADD(at[7], at[33]); MULADD(at[8], at[32]); 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]); MULADD(at[16], at[24]); COMBA_STORE(C->dp[23]); /* 24 */ COMBA_FORWARD; MULADD(at[8], at[33]); MULADD(at[9], at[32]); 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]); MULADD(at[16], at[25]); COMBA_STORE(C->dp[24]); /* 25 */ COMBA_FORWARD; MULADD(at[9], at[33]); MULADD(at[10], at[32]); 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]); MULADD(at[16], at[26]); COMBA_STORE(C->dp[25]); /* 26 */ COMBA_FORWARD; MULADD(at[10], at[33]); MULADD(at[11], at[32]); MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); MULADD(at[16], at[27]); COMBA_STORE(C->dp[26]); /* 27 */ COMBA_FORWARD; MULADD(at[11], at[33]); MULADD(at[12], at[32]); MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); MULADD(at[16], at[28]); COMBA_STORE(C->dp[27]); /* 28 */ COMBA_FORWARD; MULADD(at[12], at[33]); MULADD(at[13], at[32]); MULADD(at[14], at[31]); MULADD(at[15], at[30]); MULADD(at[16], at[29]); COMBA_STORE(C->dp[28]); /* 29 */ COMBA_FORWARD; MULADD(at[13], at[33]); MULADD(at[14], at[32]); MULADD(at[15], at[31]); MULADD(at[16], at[30]); COMBA_STORE(C->dp[29]); /* 30 */ COMBA_FORWARD; MULADD(at[14], at[33]); MULADD(at[15], at[32]); MULADD(at[16], at[31]); COMBA_STORE(C->dp[30]); /* 31 */ COMBA_FORWARD; MULADD(at[15], at[33]); MULADD(at[16], at[32]); COMBA_STORE(C->dp[31]); /* 32 */ COMBA_FORWARD; MULADD(at[16], at[33]); COMBA_STORE(C->dp[32]); COMBA_STORE2(C->dp[33]); C->used = 34; C->sign = A->sign ^ B->sign; fp_clamp(C); COMBA_FINI; }
/* a/b => cb + d == a */ int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d) { fp_int q, x, y, t1, t2; int n, t, i, norm, neg; /* is divisor zero ? */ if (fp_iszero (b) == 1) { return FP_VAL; } /* if a < b then q=0, r = a */ if (fp_cmp_mag (a, b) == FP_LT) { if (d != NULL) { fp_copy (a, d); } if (c != NULL) { fp_zero (c); } return FP_OKAY; } fp_init(&q); q.used = a->used + 2; fp_init(&t1); fp_init(&t2); fp_init_copy(&x, a); fp_init_copy(&y, b); /* fix the sign */ neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG; x.sign = y.sign = FP_ZPOS; /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ norm = fp_count_bits(&y) % DIGIT_BIT; if (norm < (int)(DIGIT_BIT-1)) { norm = (DIGIT_BIT-1) - norm; fp_mul_2d (&x, norm, &x); fp_mul_2d (&y, norm, &y); } else { norm = 0; } /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ n = x.used - 1; t = y.used - 1; /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ fp_lshd (&y, n - t); /* y = y*b**{n-t} */ while (fp_cmp (&x, &y) != FP_LT) { ++(q.dp[n - t]); fp_sub (&x, &y, &x); } /* reset y by shifting it back down */ fp_rshd (&y, n - t); /* step 3. for i from n down to (t + 1) */ for (i = n; i >= (t + 1); i--) { if (i > x.used) { continue; } /* step 3.1 if xi == yt then set q{i-t-1} to b-1, * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ if (x.dp[i] == y.dp[t]) { q.dp[i - t - 1] = ((((fp_word)1) << DIGIT_BIT) - 1); } else { fp_word tmp; tmp = ((fp_word) x.dp[i]) << ((fp_word) DIGIT_BIT); tmp |= ((fp_word) x.dp[i - 1]); tmp /= ((fp_word) y.dp[t]); q.dp[i - t - 1] = (fp_digit) (tmp); } /* while (q{i-t-1} * (yt * b + y{t-1})) > xi * b**2 + xi-1 * b + xi-2 do q{i-t-1} -= 1; */ q.dp[i - t - 1] = (q.dp[i - t - 1] + 1); do { q.dp[i - t - 1] = (q.dp[i - t - 1] - 1); /* find left hand */ fp_zero (&t1); t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; t1.dp[1] = y.dp[t]; t1.used = 2; fp_mul_d (&t1, q.dp[i - t - 1], &t1); /* find right hand */ t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; t2.dp[2] = x.dp[i]; t2.used = 3; } while (fp_cmp_mag(&t1, &t2) == FP_GT); /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ fp_mul_d (&y, q.dp[i - t - 1], &t1); fp_lshd (&t1, i - t - 1); fp_sub (&x, &t1, &x); /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ if (x.sign == FP_NEG) { fp_copy (&y, &t1); fp_lshd (&t1, i - t - 1); fp_add (&x, &t1, &x); q.dp[i - t - 1] = q.dp[i - t - 1] - 1; } } /* now q is the quotient and x is the remainder * [which we have to normalize] */ /* get sign before writing to c */ x.sign = x.used == 0 ? FP_ZPOS : a->sign; if (c != NULL) { fp_clamp (&q); fp_copy (&q, c); c->sign = neg; } if (d != NULL) { fp_div_2d (&x, norm, &x, NULL); /* the following is a kludge, essentially we were seeing the right remainder but with excess digits that should have been zero */ for (i = b->used; i < x.used; i++) { x.dp[i] = 0; } fp_clamp(&x); fp_copy (&x, d); } return FP_OKAY; }
void fp_sqr_comba28(fp_int *A, fp_int *B) { fp_digit *a, b[56], c0, c1, c2, sc0, sc1, sc2; #ifdef TFM_ISO fp_word tt; #endif a = A->dp; COMBA_START; /* clear carries */ CLEAR_CARRY; /* output 0 */ SQRADD(a[0],a[0]); COMBA_STORE(b[0]); /* output 1 */ CARRY_FORWARD; SQRADD2(a[0], a[1]); COMBA_STORE(b[1]); /* output 2 */ CARRY_FORWARD; SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); COMBA_STORE(b[2]); /* output 3 */ CARRY_FORWARD; SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); COMBA_STORE(b[3]); /* output 4 */ CARRY_FORWARD; SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); COMBA_STORE(b[4]); /* output 5 */ CARRY_FORWARD; SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; COMBA_STORE(b[5]); /* output 6 */ CARRY_FORWARD; SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); COMBA_STORE(b[6]); /* output 7 */ CARRY_FORWARD; SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; COMBA_STORE(b[7]); /* output 8 */ CARRY_FORWARD; 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]); COMBA_STORE(b[8]); /* output 9 */ CARRY_FORWARD; 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; COMBA_STORE(b[9]); /* output 10 */ CARRY_FORWARD; 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]); COMBA_STORE(b[10]); /* output 11 */ CARRY_FORWARD; 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; COMBA_STORE(b[11]); /* output 12 */ CARRY_FORWARD; 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]); COMBA_STORE(b[12]); /* output 13 */ CARRY_FORWARD; 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; COMBA_STORE(b[13]); /* output 14 */ CARRY_FORWARD; 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]); COMBA_STORE(b[14]); /* output 15 */ CARRY_FORWARD; 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; COMBA_STORE(b[15]); /* output 16 */ CARRY_FORWARD; 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]); COMBA_STORE(b[16]); /* output 17 */ CARRY_FORWARD; 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; COMBA_STORE(b[17]); /* output 18 */ CARRY_FORWARD; 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]); COMBA_STORE(b[18]); /* output 19 */ CARRY_FORWARD; 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; COMBA_STORE(b[19]); /* output 20 */ CARRY_FORWARD; 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]); COMBA_STORE(b[20]); /* output 21 */ CARRY_FORWARD; 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; COMBA_STORE(b[21]); /* output 22 */ CARRY_FORWARD; 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]); COMBA_STORE(b[22]); /* output 23 */ CARRY_FORWARD; 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; COMBA_STORE(b[23]); /* output 24 */ CARRY_FORWARD; 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]); COMBA_STORE(b[24]); /* output 25 */ CARRY_FORWARD; 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; COMBA_STORE(b[25]); /* output 26 */ CARRY_FORWARD; 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]); COMBA_STORE(b[26]); /* output 27 */ CARRY_FORWARD; 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; COMBA_STORE(b[27]); /* output 28 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[28]); /* output 29 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[29]); /* output 30 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[30]); /* output 31 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[31]); /* output 32 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[32]); /* output 33 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[33]); /* output 34 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[34]); /* output 35 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[35]); /* output 36 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[36]); /* output 37 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[37]); /* output 38 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[38]); /* output 39 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[39]); /* output 40 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[40]); /* output 41 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[41]); /* output 42 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[42]); /* output 43 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[43]); /* output 44 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[44]); /* output 45 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[45]); /* output 46 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[46]); /* output 47 */ CARRY_FORWARD; SQRADDSC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; COMBA_STORE(b[47]); /* output 48 */ CARRY_FORWARD; SQRADDSC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); COMBA_STORE(b[48]); /* output 49 */ CARRY_FORWARD; SQRADDSC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; COMBA_STORE(b[49]); /* output 50 */ CARRY_FORWARD; SQRADD2(a[23], a[27]); SQRADD2(a[24], a[26]); SQRADD(a[25], a[25]); COMBA_STORE(b[50]); /* output 51 */ CARRY_FORWARD; SQRADD2(a[24], a[27]); SQRADD2(a[25], a[26]); COMBA_STORE(b[51]); /* output 52 */ CARRY_FORWARD; SQRADD2(a[25], a[27]); SQRADD(a[26], a[26]); COMBA_STORE(b[52]); /* output 53 */ CARRY_FORWARD; SQRADD2(a[26], a[27]); COMBA_STORE(b[53]); /* output 54 */ CARRY_FORWARD; SQRADD(a[27], a[27]); COMBA_STORE(b[54]); COMBA_STORE2(b[55]); COMBA_FINI; B->used = 56; B->sign = FP_ZPOS; memcpy(B->dp, b, 56 * sizeof(fp_digit)); memset(B->dp + 56, 0, (FP_SIZE - 56) * sizeof(fp_digit)); fp_clamp(B); }
/* computes x/R == x (mod N) via Montgomery Reduction */ void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) { fp_digit c[FP_SIZE], *_c, *tmpm, mu; int oldused, x, y, pa; /* bail if too large */ if (m->used > (FP_SIZE/2)) { return; } #ifdef TFM_SMALL_MONT_SET if (m->used <= 16) { fp_montgomery_reduce_small(a, m, mp); return; } #endif #if defined(USE_MEMSET) /* now zero the buff */ memset(c, 0, sizeof c); #endif pa = m->used; /* copy the input */ oldused = a->used; for (x = 0; x < oldused; x++) { c[x] = a->dp[x]; } #if !defined(USE_MEMSET) for (; x < 2*pa+1; x++) { c[x] = 0; } #endif MONT_START; for (x = 0; x < pa; x++) { fp_digit cy = 0; /* get Mu for this round */ LOOP_START; _c = c + x; tmpm = m->dp; y = 0; #if (defined(TFM_SSE2) || defined(TFM_X86_64)) for (; y < (pa & ~7); y += 8) { INNERMUL8; _c += 8; tmpm += 8; } #endif for (; y < pa; y++) { INNERMUL; ++_c; } LOOP_END; while (cy) { PROPCARRY; ++_c; } } /* now copy out */ _c = c + pa; tmpm = a->dp; for (x = 0; x < pa+1; x++) { *tmpm++ = *_c++; } for (; x < oldused; x++) { *tmpm++ = 0; } MONT_FINI; a->used = pa+1; fp_clamp(a); /* if A >= m then A = A - m */ if (fp_cmp_mag (a, m) != FP_LT) { s_fp_sub (a, m, a); } }
void fp_mul_comba(z *A, z *B, z *C) { int ix, iy, iz, tx, ty, pa, sA, sB; fp_digit c0, c1, c2, *tmpx, *tmpy; z *dst; z loc; COMBA_START; COMBA_CLEAR; /* get size of output and trim */ sA = abs(A->size); sB = abs(B->size); pa = sA + sB; if (A == C || B == C) { zInit(&loc); //dst = &atmp1; dst = &loc; } else { dst = C; } if (dst->alloc < pa) zGrow(dst,pa + LIMB_BLKSZ); zClear(dst); for (ix = 0; ix < pa; ix++) { /* get offsets into the two bignums */ ty = MIN(ix, sB-1); tx = ix - ty; /* setup temp aliases */ tmpx = A->val + tx; tmpy = B->val + ty; /* this is the number of times the loop will iterrate, essentially its while (tx++ < a->used && ty-- >= 0) { ... } */ iy = MIN(sA-tx, ty+1); /* execute loop */ COMBA_FORWARD; for (iz = 0; iz < iy; ++iz) { MULADD(*tmpx++, *tmpy--); } /* store term */ COMBA_STORE(dst->val[ix]); } COMBA_FINI; dst->size = pa; if ((A->size * B->size) < 0) dst->size *= -1; fp_clamp(dst); if (dst != C) { zCopy(dst, C); zFree(&loc); } }
void fp_sqr_comba7(fp_int *A, fp_int *B) { fp_digit *a, b[14], c0, c1, c2, sc0, sc1, sc2; #ifdef TFM_ISO fp_word tt; #endif a = A->dp; COMBA_START; /* clear carries */ CLEAR_CARRY; /* output 0 */ SQRADD(a[0],a[0]); COMBA_STORE(b[0]); /* output 1 */ CARRY_FORWARD; SQRADD2(a[0], a[1]); COMBA_STORE(b[1]); /* output 2 */ CARRY_FORWARD; SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); COMBA_STORE(b[2]); /* output 3 */ CARRY_FORWARD; SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); COMBA_STORE(b[3]); /* output 4 */ CARRY_FORWARD; SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); COMBA_STORE(b[4]); /* output 5 */ CARRY_FORWARD; SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; COMBA_STORE(b[5]); /* output 6 */ CARRY_FORWARD; SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); COMBA_STORE(b[6]); /* output 7 */ CARRY_FORWARD; SQRADDSC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; COMBA_STORE(b[7]); /* output 8 */ CARRY_FORWARD; SQRADD2(a[2], a[6]); SQRADD2(a[3], a[5]); SQRADD(a[4], a[4]); COMBA_STORE(b[8]); /* output 9 */ CARRY_FORWARD; SQRADD2(a[3], a[6]); SQRADD2(a[4], a[5]); COMBA_STORE(b[9]); /* output 10 */ CARRY_FORWARD; SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]); COMBA_STORE(b[10]); /* output 11 */ CARRY_FORWARD; SQRADD2(a[5], a[6]); COMBA_STORE(b[11]); /* output 12 */ CARRY_FORWARD; SQRADD(a[6], a[6]); COMBA_STORE(b[12]); COMBA_STORE2(b[13]); COMBA_FINI; B->used = 14; B->sign = FP_ZPOS; memcpy(B->dp, b, 14 * sizeof(fp_digit)); memset(B->dp + 14, 0, (FP_SIZE - 14) * sizeof(fp_digit)); fp_clamp(B); }
int do_rsa_proc(char *pSRC, int nDataLen,char *pOUT,int *pOUTLen,fp_int *key, int procedure) { // fp_int *key--> key[0], key[1], key[2] int in_size = nDataLen; int nret=-1; int nlen; fp_int c,m; fp_int* k,* t; unsigned char *pSRCBuff = (unsigned char *)pSRC; unsigned char *pOUTBuff = (unsigned char *)pOUT; memset(pOUTBuff,0,*pOUTLen); *pOUTLen = 0; //get key length //for RSA1024 : 1028bit -> 128 bytes //dec-i_len : 128 dec-o_len:127 //enc-i_len : 127 dec-o_len:128 uint32_t bits=fp_count_bits(&key[0]); uint32_t o_len,i_len; //dec i_len=(bits+7)>>3; o_len=i_len-1; //pub key k=&key[1]; switch(procedure & RSA_ENC_DEC_MASK) { case ENC_WITH_PRIV:o_len=i_len;--i_len;;k=&key[2];break; case DEC_WITH_PUB:break; case ENC_WITH_PUB:o_len=i_len;--i_len;break; case DEC_WITH_PRIV:k=&key[2];break; default: //printf("Internal error! Not support this enc-dec mode %d\n",procedure); //dbg_print("Internal error! Not support this enc-dec mode ", procedure); return nret; break; } //buffer process if((procedure & RSA_BUF_IN_TYPE_MASK) != RSA_BUF_IN_TYPE_IGNORE) aml_buffer_proc_before(pSRCBuff,nDataLen,i_len,procedure); for(nlen=0;nlen<in_size;nlen+=i_len) { fp_init(&c); fp_init(&m); memcpy(c.dp,pSRCBuff,i_len); pSRCBuff += i_len; c.used=FP_SIZE; fp_clamp(&c); fp_exptmod(&c,k,&key[0],&m); memcpy(pOUTBuff+*pOUTLen,m.dp,o_len); *pOUTLen += o_len; } //buffer process if((procedure & RSA_BUF_OUT_TYPE_MASK) != RSA_BUF_OUT_TYPE_IGNORE) aml_buffer_proc_after(pOUTBuff,pOUTLen,o_len,procedure); nret = 0; return nret; }
void fp_sqr_comba17(fp_int *A, fp_int *B) { fp_digit *a, b[34], c0, c1, c2, sc0, sc1, sc2; #ifdef TFM_ISO fp_word tt; #endif a = A->dp; COMBA_START; /* clear carries */ CLEAR_CARRY; /* output 0 */ SQRADD(a[0],a[0]); COMBA_STORE(b[0]); /* output 1 */ CARRY_FORWARD; SQRADD2(a[0], a[1]); COMBA_STORE(b[1]); /* output 2 */ CARRY_FORWARD; SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); COMBA_STORE(b[2]); /* output 3 */ CARRY_FORWARD; SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); COMBA_STORE(b[3]); /* output 4 */ CARRY_FORWARD; SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); COMBA_STORE(b[4]); /* output 5 */ CARRY_FORWARD; SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; COMBA_STORE(b[5]); /* output 6 */ CARRY_FORWARD; SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); COMBA_STORE(b[6]); /* output 7 */ CARRY_FORWARD; SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; COMBA_STORE(b[7]); /* output 8 */ CARRY_FORWARD; 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]); COMBA_STORE(b[8]); /* output 9 */ CARRY_FORWARD; 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; COMBA_STORE(b[9]); /* output 10 */ CARRY_FORWARD; 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]); COMBA_STORE(b[10]); /* output 11 */ CARRY_FORWARD; 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; COMBA_STORE(b[11]); /* output 12 */ CARRY_FORWARD; 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]); COMBA_STORE(b[12]); /* output 13 */ CARRY_FORWARD; 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; COMBA_STORE(b[13]); /* output 14 */ CARRY_FORWARD; 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]); COMBA_STORE(b[14]); /* output 15 */ CARRY_FORWARD; 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; COMBA_STORE(b[15]); /* output 16 */ CARRY_FORWARD; 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]); COMBA_STORE(b[16]); /* output 17 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[17]); /* output 18 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[18]); /* output 19 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[19]); /* output 20 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[20]); /* output 21 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[21]); /* output 22 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[22]); /* output 23 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[23]); /* output 24 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[24]); /* output 25 */ CARRY_FORWARD; SQRADDSC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; COMBA_STORE(b[25]); /* output 26 */ CARRY_FORWARD; SQRADDSC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); COMBA_STORE(b[26]); /* output 27 */ CARRY_FORWARD; SQRADDSC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; COMBA_STORE(b[27]); /* output 28 */ CARRY_FORWARD; SQRADD2(a[12], a[16]); SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]); COMBA_STORE(b[28]); /* output 29 */ CARRY_FORWARD; SQRADD2(a[13], a[16]); SQRADD2(a[14], a[15]); COMBA_STORE(b[29]); /* output 30 */ CARRY_FORWARD; SQRADD2(a[14], a[16]); SQRADD(a[15], a[15]); COMBA_STORE(b[30]); /* output 31 */ CARRY_FORWARD; SQRADD2(a[15], a[16]); COMBA_STORE(b[31]); /* output 32 */ CARRY_FORWARD; SQRADD(a[16], a[16]); COMBA_STORE(b[32]); COMBA_STORE2(b[33]); COMBA_FINI; B->used = 34; B->sign = FP_ZPOS; memcpy(B->dp, b, 34 * sizeof(fp_digit)); fp_clamp(B); }
/* a/b => cb + d == a */ int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) { fp_int q; fp_word w; fp_digit t; int ix; /* cannot divide by zero */ if (b == 0) { return FP_VAL; } /* quick outs */ if (b == 1 || fp_iszero(a) == 1) { if (d != NULL) { *d = 0; } if (c != NULL) { fp_copy(a, c); } return FP_OKAY; } /* power of two ? */ if (s_is_power_of_two(b, &ix) == 1) { if (d != NULL) { *d = a->dp[0] & ((((fp_digit)1)<<ix) - 1); } if (c != NULL) { fp_div_2d(a, ix, c, NULL); } return FP_OKAY; } /* no easy answer [c'est la vie]. Just division */ fp_init(&q); q.used = a->used; q.sign = a->sign; w = 0; for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]); if (w >= b) { t = (fp_digit)(w / b); w -= ((fp_word)t) * ((fp_word)b); } else { t = 0; } q.dp[ix] = (fp_digit)t; } if (d != NULL) { *d = (fp_digit)w; } if (c != NULL) { fp_clamp(&q); fp_copy(&q, c); } return FP_OKAY; }
void fp_sqr_comba48(fp_int *A, fp_int *B) { fp_digit *a, b[96], c0, c1, c2, sc0, sc1, sc2; #ifdef TFM_ISO fp_word tt; #endif a = A->dp; COMBA_START; /* clear carries */ CLEAR_CARRY; /* output 0 */ SQRADD(a[0],a[0]); COMBA_STORE(b[0]); /* output 1 */ CARRY_FORWARD; SQRADD2(a[0], a[1]); COMBA_STORE(b[1]); /* output 2 */ CARRY_FORWARD; SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); COMBA_STORE(b[2]); /* output 3 */ CARRY_FORWARD; SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); COMBA_STORE(b[3]); /* output 4 */ CARRY_FORWARD; SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); COMBA_STORE(b[4]); /* output 5 */ CARRY_FORWARD; SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; COMBA_STORE(b[5]); /* output 6 */ CARRY_FORWARD; SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); COMBA_STORE(b[6]); /* output 7 */ CARRY_FORWARD; SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; COMBA_STORE(b[7]); /* output 8 */ CARRY_FORWARD; 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]); COMBA_STORE(b[8]); /* output 9 */ CARRY_FORWARD; 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; COMBA_STORE(b[9]); /* output 10 */ CARRY_FORWARD; 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]); COMBA_STORE(b[10]); /* output 11 */ CARRY_FORWARD; 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; COMBA_STORE(b[11]); /* output 12 */ CARRY_FORWARD; 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]); COMBA_STORE(b[12]); /* output 13 */ CARRY_FORWARD; 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; COMBA_STORE(b[13]); /* output 14 */ CARRY_FORWARD; 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]); COMBA_STORE(b[14]); /* output 15 */ CARRY_FORWARD; 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; COMBA_STORE(b[15]); /* output 16 */ CARRY_FORWARD; 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]); COMBA_STORE(b[16]); /* output 17 */ CARRY_FORWARD; 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; COMBA_STORE(b[17]); /* output 18 */ CARRY_FORWARD; 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]); COMBA_STORE(b[18]); /* output 19 */ CARRY_FORWARD; 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; COMBA_STORE(b[19]); /* output 20 */ CARRY_FORWARD; 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]); COMBA_STORE(b[20]); /* output 21 */ CARRY_FORWARD; 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; COMBA_STORE(b[21]); /* output 22 */ CARRY_FORWARD; 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]); COMBA_STORE(b[22]); /* output 23 */ CARRY_FORWARD; 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; COMBA_STORE(b[23]); /* output 24 */ CARRY_FORWARD; 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]); COMBA_STORE(b[24]); /* output 25 */ CARRY_FORWARD; 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; COMBA_STORE(b[25]); /* output 26 */ CARRY_FORWARD; 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]); COMBA_STORE(b[26]); /* output 27 */ CARRY_FORWARD; 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; COMBA_STORE(b[27]); /* output 28 */ CARRY_FORWARD; 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]); COMBA_STORE(b[28]); /* output 29 */ CARRY_FORWARD; 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; COMBA_STORE(b[29]); /* output 30 */ CARRY_FORWARD; 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]); COMBA_STORE(b[30]); /* output 31 */ CARRY_FORWARD; 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; COMBA_STORE(b[31]); /* output 32 */ CARRY_FORWARD; 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]); COMBA_STORE(b[32]); /* output 33 */ CARRY_FORWARD; 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; COMBA_STORE(b[33]); /* output 34 */ CARRY_FORWARD; 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]); COMBA_STORE(b[34]); /* output 35 */ CARRY_FORWARD; 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; COMBA_STORE(b[35]); /* output 36 */ CARRY_FORWARD; 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]); COMBA_STORE(b[36]); /* output 37 */ CARRY_FORWARD; 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; COMBA_STORE(b[37]); /* output 38 */ CARRY_FORWARD; 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]); COMBA_STORE(b[38]); /* output 39 */ CARRY_FORWARD; 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; COMBA_STORE(b[39]); /* output 40 */ CARRY_FORWARD; 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]); COMBA_STORE(b[40]); /* output 41 */ CARRY_FORWARD; 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; COMBA_STORE(b[41]); /* output 42 */ CARRY_FORWARD; 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]); COMBA_STORE(b[42]); /* output 43 */ CARRY_FORWARD; 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; COMBA_STORE(b[43]); /* output 44 */ CARRY_FORWARD; 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]); COMBA_STORE(b[44]); /* output 45 */ CARRY_FORWARD; 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; COMBA_STORE(b[45]); /* output 46 */ CARRY_FORWARD; 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]); COMBA_STORE(b[46]); /* output 47 */ CARRY_FORWARD; 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; COMBA_STORE(b[47]); /* output 48 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[48]); /* output 49 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[49]); /* output 50 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[50]); /* output 51 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[51]); /* output 52 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[52]); /* output 53 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[53]); /* output 54 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[54]); /* output 55 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[55]); /* output 56 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[56]); /* output 57 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[57]); /* output 58 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[58]); /* output 59 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[59]); /* output 60 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[60]); /* output 61 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[61]); /* output 62 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[62]); /* output 63 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[63]); /* output 64 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[64]); /* output 65 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[65]); /* output 66 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[66]); /* output 67 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[67]); /* output 68 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[68]); /* output 69 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[69]); /* output 70 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[70]); /* output 71 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[71]); /* output 72 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[72]); /* output 73 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[73]); /* output 74 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[74]); /* output 75 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[75]); /* output 76 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[76]); /* output 77 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[77]); /* output 78 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[78]); /* output 79 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[79]); /* output 80 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[80]); /* output 81 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[81]); /* output 82 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[82]); /* output 83 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[83]); /* output 84 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[84]); /* output 85 */ CARRY_FORWARD; SQRADDSC(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; COMBA_STORE(b[85]); /* output 86 */ CARRY_FORWARD; SQRADDSC(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]); COMBA_STORE(b[86]); /* output 87 */ CARRY_FORWARD; SQRADDSC(a[40], a[47]); SQRADDAC(a[41], a[46]); SQRADDAC(a[42], a[45]); SQRADDAC(a[43], a[44]); SQRADDDB; COMBA_STORE(b[87]); /* output 88 */ CARRY_FORWARD; SQRADDSC(a[41], a[47]); SQRADDAC(a[42], a[46]); SQRADDAC(a[43], a[45]); SQRADDDB; SQRADD(a[44], a[44]); COMBA_STORE(b[88]); /* output 89 */ CARRY_FORWARD; SQRADDSC(a[42], a[47]); SQRADDAC(a[43], a[46]); SQRADDAC(a[44], a[45]); SQRADDDB; COMBA_STORE(b[89]); /* output 90 */ CARRY_FORWARD; SQRADD2(a[43], a[47]); SQRADD2(a[44], a[46]); SQRADD(a[45], a[45]); COMBA_STORE(b[90]); /* output 91 */ CARRY_FORWARD; SQRADD2(a[44], a[47]); SQRADD2(a[45], a[46]); COMBA_STORE(b[91]); /* output 92 */ CARRY_FORWARD; SQRADD2(a[45], a[47]); SQRADD(a[46], a[46]); COMBA_STORE(b[92]); /* output 93 */ CARRY_FORWARD; SQRADD2(a[46], a[47]); COMBA_STORE(b[93]); /* output 94 */ CARRY_FORWARD; SQRADD(a[47], a[47]); COMBA_STORE(b[94]); COMBA_STORE2(b[95]); COMBA_FINI; B->used = 96; B->sign = FP_ZPOS; memcpy(B->dp, b, 96 * sizeof(fp_digit)); fp_clamp(B); }