void ep_mul_sim_basic(ep_t r, const ep_t p, const bn_t k, const ep_t q, const bn_t m) { ep_t t; ep_null(t); TRY { ep_new(t); ep_mul(t, q, m); ep_mul(r, p, k); ep_add(t, t, r); ep_norm(r, t); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep_free(t); } }
void ep_mul_sim_gen(ep_t r, const bn_t k, const ep_t q, const bn_t m) { ep_t g; ep_null(g); if (bn_is_zero(k)) { ep_mul(r, q, m); return; } if (bn_is_zero(m) || ep_is_infty(q)) { ep_mul_gen(r, k); return; } TRY { ep_new(g); ep_curve_get_gen(g); #if defined(EP_ENDOM) #if EP_SIM == INTER && EP_FIX == LWNAF && defined(EP_PRECO) if (ep_curve_is_endom()) { ep_mul_sim_endom(r, g, k, q, m, ep_curve_get_tab()); } #else if (ep_curve_is_endom()) { ep_mul_sim(r, g, k, q, m); } #endif #endif #if defined(EP_PLAIN) || defined(EP_SUPER) #if EP_SIM == INTER && EP_FIX == LWNAF && defined(EP_PRECO) if (!ep_curve_is_endom()) { ep_mul_sim_plain(r, g, k, q, m, ep_curve_get_tab()); } #else if (!ep_curve_is_endom()) { ep_mul_sim(r, g, k, q, m); } #endif #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep_free(g); } }
void ep_mul_sim_inter(ep_t r, const ep_t p, const bn_t k, const ep_t q, const bn_t m) { if (bn_is_zero(k) || ep_is_infty(p)) { ep_mul(r, q, m); return; } if (bn_is_zero(m) || ep_is_infty(q)) { ep_mul(r, p, k); return; } #if defined(EP_ENDOM) if (ep_curve_is_endom()) { ep_mul_sim_endom(r, p, k, q, m, NULL); return; } #endif #if defined(EP_PLAIN) || defined(EP_SUPER) ep_mul_sim_plain(r, p, k, q, m, NULL); #endif }
void ep_mul_sim_joint(ep_t r, const ep_t p, const bn_t k, const ep_t q, const bn_t m) { ep_t t[5]; int i, u_i, len, offset; int8_t jsf[2 * (FP_BITS + 1)]; if (bn_is_zero(k) || ep_is_infty(p)) { ep_mul(r, q, m); return; } if (bn_is_zero(m) || ep_is_infty(q)) { ep_mul(r, p, k); return; } TRY { for (i = 0; i < 5; i++) { ep_null(t[i]); ep_new(t[i]); } ep_set_infty(t[0]); ep_copy(t[1], q); if (bn_sign(m) == BN_NEG) { ep_neg(t[1], t[1]); } ep_copy(t[2], p); if (bn_sign(k) == BN_NEG) { ep_neg(t[2], t[2]); } ep_add(t[3], t[2], t[1]); ep_sub(t[4], t[2], t[1]); #if defined(EP_MIXED) ep_norm_sim(t + 3, (const ep_t *)t + 3, 2); #endif len = 2 * (FP_BITS + 1); bn_rec_jsf(jsf, &len, k, m); ep_set_infty(r); offset = MAX(bn_bits(k), bn_bits(m)) + 1; for (i = len - 1; i >= 0; i--) { ep_dbl(r, r); if (jsf[i] != 0 && jsf[i] == -jsf[i + offset]) { u_i = jsf[i] * 2 + jsf[i + offset]; if (u_i < 0) { ep_sub(r, r, t[4]); } else { ep_add(r, r, t[4]); } } else { u_i = jsf[i] * 2 + jsf[i + offset]; if (u_i < 0) { ep_sub(r, r, t[-u_i]); } else { ep_add(r, r, t[u_i]); } } } ep_norm(r, r); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 0; i < 5; i++) { ep_free(t[i]); } } }
void ep_mul_sim_trick(ep_t r, const ep_t p, const bn_t k, const ep_t q, const bn_t m) { ep_t t0[1 << (EP_WIDTH / 2)], t1[1 << (EP_WIDTH / 2)], t[1 << EP_WIDTH]; bn_t n; int l0, l1, w = EP_WIDTH / 2; uint8_t w0[CEIL(FP_BITS + 1, w)], w1[CEIL(FP_BITS + 1, w)]; bn_null(n); if (bn_is_zero(k) || ep_is_infty(p)) { ep_mul(r, q, m); return; } if (bn_is_zero(m) || ep_is_infty(q)) { ep_mul(r, p, k); return; } TRY { bn_new(n); ep_curve_get_ord(n); for (int i = 0; i < (1 << w); i++) { ep_null(t0[i]); ep_null(t1[i]); ep_new(t0[i]); ep_new(t1[i]); } for (int i = 0; i < (1 << EP_WIDTH); i++) { ep_null(t[i]); ep_new(t[i]); } ep_set_infty(t0[0]); ep_copy(t0[1], p); if (bn_sign(k) == BN_NEG) { ep_neg(t0[1], t0[1]); } for (int i = 2; i < (1 << w); i++) { ep_add(t0[i], t0[i - 1], t0[1]); } ep_set_infty(t1[0]); ep_copy(t1[1], q); if (bn_sign(m) == BN_NEG) { ep_neg(t1[1], t1[1]); } for (int i = 1; i < (1 << w); i++) { ep_add(t1[i], t1[i - 1], t1[1]); } for (int i = 0; i < (1 << w); i++) { for (int j = 0; j < (1 << w); j++) { ep_add(t[(i << w) + j], t0[i], t1[j]); } } #if defined(EP_MIXED) ep_norm_sim(t + 1, (const ep_t *)t + 1, (1 << (EP_WIDTH)) - 1); #endif l0 = l1 = CEIL(FP_BITS, w); bn_rec_win(w0, &l0, k, w); bn_rec_win(w1, &l1, m, w); for (int i = l0; i < l1; i++) { w0[i] = 0; } for (int i = l1; i < l0; i++) { w1[i] = 0; } ep_set_infty(r); for (int i = MAX(l0, l1) - 1; i >= 0; i--) { for (int j = 0; j < w; j++) { ep_dbl(r, r); } ep_add(r, r, t[(w0[i] << w) + w1[i]]); } ep_norm(r, r); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); for (int i = 0; i < (1 << w); i++) { ep_free(t0[i]); ep_free(t1[i]); } for (int i = 0; i < (1 << EP_WIDTH); i++) { ep_free(t[i]); } } }