void bn_modn_low(dig_t *c, const dig_t *a, int sa, const dig_t *m, int sm, dig_t u) { int i, j; dig_t r0, r1, r2; dig_t *tmp, *tmpc; const dig_t *tmpm; tmpc = c; r0 = r1 = r2 = 0; for (i = 0; i < sm; i++, tmpc++, a++) { tmp = c; tmpm = m + i; for (j = 0; j < i; j++, tmp++, tmpm--) { COMBA_STEP(r2, r1, r0, *tmp, *tmpm); } if (i < sa) { COMBA_ADD(r2, r1, r0, *a); } *tmpc = (dig_t)(r0 * u); COMBA_STEP(r2, r1, r0, *tmpc, *m); r0 = r1; r1 = r2; r2 = 0; } for (i = sm; i < 2 * sm - 1; i++, a++) { tmp = c + (i - sm + 1); tmpm = m + sm - 1; for (j = i - sm + 1; j < sm; j++, tmp++, tmpm--) { COMBA_STEP(r2, r1, r0, *tmp, *tmpm); } if (i < sa) { COMBA_ADD(r2, r1, r0, *a); } c[i - sm] = r0; r0 = r1; r1 = r2; r2 = 0; } if (i < sa) { COMBA_ADD(r2, r1, r0, *a); } c[sm - 1] = r0; if (r1) { bn_subn_low(c, c, m, sm); } }
void fp_rdcn_low2(dig_t *c, dig_t *a) { int i, j; dig_t r0, r1, r2, u; dig_t *m, *tmp, *tmpm, *tmpc; u = *(fp_prime_get_rdc()); m = fp_prime_get(); tmpc = c; r0 = r1 = r2 = 0; for (i = 0; i < FP_DIGS; i++, tmpc++, a++) { tmp = c; tmpm = m + i; for (j = 0; j < i; j++, tmp++, tmpm--) { COMBA_STEP(r2, r1, r0, *tmp, *tmpm); } COMBA_ADD(r2, r1, r0, *a); *tmpc = (dig_t)(r0 * u); COMBA_STEP(r2, r1, r0, *tmpc, *m); r0 = r1; r1 = r2; r2 = 0; } for (i = FP_DIGS; i < 2 * FP_DIGS - 1; i++, a++) { tmp = c + (i - FP_DIGS + 1); tmpm = m + FP_DIGS - 1; for (j = i - FP_DIGS + 1; j < FP_DIGS; j++, tmp++, tmpm--) { COMBA_STEP(r2, r1, r0, *tmp, *tmpm); } COMBA_ADD(r2, r1, r0, *a); c[i - FP_DIGS] = r0; r0 = r1; r1 = r2; r2 = 0; } COMBA_ADD(r2, r1, r0, *a); c[FP_DIGS - 1] = r0; if (r1 || fp_cmpn_low(c, m) != CMP_LT) { fp_subn_low(c, c, m); } }