void fp_rdc_monty_basic(fp_t c, dv_t a) { int i; dig_t r, c0, c1, *tmp, u0; const dig_t *p = NULL; tmp = a; u0 = *(fp_prime_get_rdc()); p = fp_prime_get(); c1 = 0; for (i = 0; i < FP_DIGS; i++, tmp++) { r = (dig_t)(*tmp * u0); c0 = fp_mula_low(tmp, fp_prime_get(), r); /* We must use this because the size (FP_DIGS - i) is variable. */ c1 += bn_add1_low(tmp + FP_DIGS, tmp + FP_DIGS, c0, FP_DIGS - i); } fp_copy(c, a + FP_DIGS); for (i = 0; i < c1; i++) { fp_subn_low(c, c, p); } if (fp_cmpn_low(c, p) != CMP_LT) { fp_subn_low(c, c, p); } }
void fp_mul_basic(fp_t c, const fp_t a, const fp_t b) { int i; dv_t t; dig_t carry; dv_null(t); TRY { /* We need a temporary variable so that c can be a or b. */ dv_new(t); dv_zero(t, 2 * FP_DIGS); for (i = 0; i < FP_DIGS; i++) { carry = fp_mula_low(t + i, b, *(a + i)); *(t + i + FP_DIGS) = carry; } fp_rdc(c, t); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { dv_free(t); } }