void bn_mxp_monty(bn_t c, const bn_t a, const bn_t b, const bn_t m) { bn_t tab[2], u; dig_t mask; int t; bn_null(tab[0]); bn_null(tab[1]); bn_null(u); TRY { bn_new(u); bn_mod_pre(u, m); bn_new(tab[0]); bn_new(tab[1]); #if BN_MOD == MONTY bn_set_dig(tab[0], 1); bn_mod_monty_conv(tab[0], tab[0], m); bn_mod_monty_conv(tab[1], a, m); #else bn_set_dig(tab[0], 1); bn_copy(tab[1], a); #endif for (int i = bn_bits(b) - 1; i >= 0; i--) { int j = bn_get_bit(b, i); dv_swap_cond(tab[0]->dp, tab[1]->dp, BN_DIGS, j ^ 1); mask = -(j ^ 1); t = (tab[0]->used ^ tab[1]->used) & mask; tab[0]->used ^= t; tab[1]->used ^= t; bn_mul(tab[0], tab[0], tab[1]); bn_mod(tab[0], tab[0], m, u); bn_sqr(tab[1], tab[1]); bn_mod(tab[1], tab[1], m, u); dv_swap_cond(tab[0]->dp, tab[1]->dp, BN_DIGS, j ^ 1); mask = -(j ^ 1); t = (tab[0]->used ^ tab[1]->used) & mask; tab[0]->used ^= t; tab[1]->used ^= t; } #if BN_MOD == MONTY bn_mod_monty_back(c, tab[0], m); #else bn_copy(c, tab[0]); #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(tab[1]); bn_free(tab[0]); bn_free(u); } }
void ed_mul_monty(ed_t r, const ed_t p, const bn_t k) { ed_t t[2]; ed_null(t[0]); ed_null(t[1]); if (bn_is_zero(k) || ed_is_infty(p)) { ed_set_infty(r); return; } TRY { ed_new(t[0]); ed_new(t[1]); ed_set_infty(t[0]); ed_copy(t[1], p); for (int i = bn_bits(k) - 1; i >= 0; i--) { int j = bn_get_bit(k, i); dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); #if ED_ADD == EXTND dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); #endif ed_add(t[0], t[0], t[1]); ed_dbl(t[1], t[1]); dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); #if ED_ADD == EXTND dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); #endif } ed_norm(r, t[0]); if (bn_sign(k) == RLC_NEG) { ed_neg(r, r); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ed_free(t[1]); ed_free(t[0]); } }
void fp_exp_monty(fp_t c, const fp_t a, const bn_t b) { fp_t t[2]; fp_null(t[0]); fp_null(t[1]); if (bn_is_zero(b)) { fp_set_dig(c, 1); return; } TRY { fp_new(t[0]); fp_new(t[1]); fp_set_dig(t[0], 1); fp_copy(t[1], a); for (int i = bn_bits(b) - 1; i >= 0; i--) { int j = bn_get_bit(b, i); dv_swap_cond(t[0], t[1], FP_DIGS, j ^ 1); fp_mul(t[0], t[0], t[1]); fp_sqr(t[1], t[1]); dv_swap_cond(t[0], t[1], FP_DIGS, j ^ 1); } if (bn_sign(b) == BN_NEG) { fp_inv(c, t[0]); } else { fp_copy(c, t[0]); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp_free(t[1]); fp_free(t[0]); } }