void ep2_mul_sim_joint(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t l) { ep2_t t[5]; int u_i, len, offset; int8_t jsf[4 * (FP_BITS + 1)]; int i; ep2_null(t[0]); ep2_null(t[1]); ep2_null(t[2]); ep2_null(t[3]); ep2_null(t[4]); TRY { for (i = 0; i < 5; i++) { ep2_new(t[i]); } ep2_set_infty(t[0]); ep2_copy(t[1], q); ep2_copy(t[2], p); ep2_add(t[3], p, q); ep2_sub(t[4], p, q); len = 4 * (FP_BITS + 1); bn_rec_jsf(jsf, &len, k, l); ep2_set_infty(r); i = bn_bits(k); offset = MAX(i, bn_bits(l)) + 1; for (i = len - 1; i >= 0; i--) { ep2_dbl(r, r); if (jsf[i] != 0 && jsf[i] == -jsf[i + offset]) { u_i = jsf[i] * 2 + jsf[i + offset]; if (u_i < 0) { ep2_sub(r, r, t[4]); } else { ep2_add(r, r, t[4]); } } else { u_i = jsf[i] * 2 + jsf[i + offset]; if (u_i < 0) { ep2_sub(r, r, t[-u_i]); } else { ep2_add(r, r, t[u_i]); } } } ep2_norm(r, r); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 0; i < 5; i++) { ep2_free(t[i]); } } }
/** * Multiplies a point on a Barreto-Lynn-Soctt curve by the cofactor. * * @param[out] r - the result. * @param[in] p - the point to multiply. */ void ep2_mul_cof_b12(ep2_t r, ep2_t p) { bn_t x; ep2_t t0, t1, t2, t3; ep2_null(t0); ep2_null(t1); ep2_null(t2); ep2_null(t3); bn_null(x); TRY { ep2_new(t0); ep2_new(t1); ep2_new(t2); ep2_new(t3); bn_new(x); fp_param_get_var(x); /* Compute t0 = xP. */ ep2_mul(t0, p, x); if (bn_sign(x) == BN_NEG) { ep2_neg(t0, t0); } /* Compute t1 = [x^2]P. */ ep2_mul(t1, t0, x); if (bn_sign(x) == BN_NEG) { ep2_neg(t1, t1); } /* t2 = (x^2 - x - 1)P = x^2P - x*P - P. */ ep2_sub(t2, t1, t0); ep2_sub(t2, t2, p); /* t3 = \psi(x - 1)P. */ ep2_sub(t3, t0, p); ep2_norm(t3, t3); ep2_frb(t3, t3, 1); ep2_add(t2, t2, t3); /* t3 = \psi^2(2P). */ ep2_dbl(t3, p); ep2_norm(t3, t3); ep2_frb(t3, t3, 2); ep2_add(t2, t2, t3); ep2_norm(r, t2); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep2_free(t0); ep2_free(t1); ep2_free(t2); ep2_free(t3); bn_free(x); } }
/** * Multiplies a binary elliptic curve point by an integer using the w-NAF * method. * * @param[out] r - the result. * @param[in] p - the point to multiply. * @param[in] k - the integer. */ static void ep2_mul_fix_ordin(ep2_t r, ep2_t *table, bn_t k) { int len, i, n; int8_t naf[2 * RLC_FP_BITS + 1], *t; if (bn_is_zero(k)) { ep2_set_infty(r); return; } /* Compute the w-TNAF representation of k. */ len = 2 * RLC_FP_BITS + 1; bn_rec_naf(naf, &len, k, EP_DEPTH); t = naf + len - 1; ep2_set_infty(r); for (i = len - 1; i >= 0; i--, t--) { ep2_dbl(r, r); n = *t; if (n > 0) { ep2_add(r, r, table[n / 2]); } if (n < 0) { ep2_sub(r, r, table[-n / 2]); } } /* Convert r to affine coordinates. */ ep2_norm(r, r); if (bn_sign(k) == RLC_NEG) { ep2_neg(r, r); } }
void ep2_mul_fix_nafwi(ep2_t r, ep2_t *t, bn_t k) { int i, j, l, d, m; ep2_t a; int8_t naf[2 * FP_BITS + 1]; char w; ep2_null(a); TRY { ep2_new(a); ep2_set_infty(r); ep2_set_infty(a); l = 2 * FP_BITS + 1; bn_rec_naf(naf, &l, k, 2); d = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); for (i = 0; i < d; i++) { w = 0; for (j = EP_DEPTH - 1; j >= 0; j--) { if (i * EP_DEPTH + j < l) { w = (char)(w << 1); w = (char)(w + naf[i * EP_DEPTH + j]); } } naf[i] = w; } if (EP_DEPTH % 2 == 0) { m = ((1 << (EP_DEPTH + 1)) - 2) / 3; } else { m = ((1 << (EP_DEPTH + 1)) - 1) / 3; } for (j = m; j >= 1; j--) { for (i = 0; i < d; i++) { if (naf[i] == j) { ep2_add(a, a, t[i]); } if (naf[i] == -j) { ep2_sub(a, a, t[i]); } } ep2_add(r, r, a); } ep2_norm(r, r); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep2_free(a); } }
static void ep2_mul_sim_plain(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t l, ep2_t *t) { int len, l0, l1, i, n0, n1, w, gen; int8_t naf0[2 * FP_BITS + 1], naf1[2 * FP_BITS + 1], *_k, *_m; ep2_t t0[1 << (EP_WIDTH - 2)]; ep2_t t1[1 << (EP_WIDTH - 2)]; for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_null(t0[i]); ep2_null(t1[i]); } TRY { gen = (t == NULL ? 0 : 1); if (!gen) { for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_new(t0[i]); } ep2_tab(t0, p, EP_WIDTH); t = (ep2_t *)t0; } /* Prepare the precomputation table. */ for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_new(t1[i]); } /* Compute the precomputation table. */ ep2_tab(t1, q, EP_WIDTH); /* Compute the w-TNAF representation of k. */ if (gen) { w = EP_DEPTH; } else { w = EP_WIDTH; } l0 = l1 = 2 * FP_BITS + 1; bn_rec_naf(naf0, &l0, k, w); bn_rec_naf(naf1, &l1, l, EP_WIDTH); len = MAX(l0, l1); _k = naf0 + len - 1; _m = naf1 + len - 1; for (i = l0; i < len; i++) naf0[i] = 0; for (i = l1; i < len; i++) naf1[i] = 0; ep2_set_infty(r); for (i = len - 1; i >= 0; i--, _k--, _m--) { ep2_dbl(r, r); n0 = *_k; n1 = *_m; if (n0 > 0) { ep2_add(r, r, t[n0 / 2]); } if (n0 < 0) { ep2_sub(r, r, t[-n0 / 2]); } if (n1 > 0) { ep2_add(r, r, t1[n1 / 2]); } if (n1 < 0) { ep2_sub(r, r, t1[-n1 / 2]); } } /* Convert r to affine coordinates. */ ep2_norm(r, r); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { /* Free the precomputation tables. */ if (!gen) { for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_free(t0[i]); } } for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_free(t1[i]); } } }
static void ep2_mul_sim_ordin(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t l, int gen) { int len, l0, l1, i, n0, n1, w; signed char naf0[FP_BITS + 1], naf1[FP_BITS + 1], *t0, *t1; ep2_t table0[1 << (EP_WIDTH - 2)]; ep2_t table1[1 << (EP_WIDTH - 2)]; ep2_t *t = NULL; for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_null(table0[i]); ep2_null(table1[i]); } if (gen) { #if defined(EP_PRECO) t = ep2_curve_get_tab(); #endif } else { for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_new(table0[i]); } ep2_tab(table0, p, EP_WIDTH); t = table0; } /* Prepare the precomputation table. */ for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { ep2_new(table1[i]); } /* Compute the precomputation table. */ ep2_tab(table1, q, EP_WIDTH); /* Compute the w-TNAF representation of k. */ if (gen) { w = EP_DEPTH; } else { w = EP_WIDTH; } l0 = l1 = FP_BITS + 1; bn_rec_naf(naf0, &l0, k, w); bn_rec_naf(naf1, &l1, l, EP_WIDTH); len = MAX(l0, l1); t0 = naf0 + len - 1; t1 = naf1 + len - 1; for (i = l0; i < len; i++) naf0[i] = 0; for (i = l1; i < len; i++) naf1[i] = 0; ep2_set_infty(r); for (i = len - 1; i >= 0; i--, t0--, t1--) { ep2_dbl(r, r); n0 = *t0; n1 = *t1; if (n0 > 0) { ep2_add(r, r, t[n0 / 2]); } if (n0 < 0) { ep2_sub(r, r, t[-n0 / 2]); } if (n1 > 0) { ep2_add(r, r, table1[n1 / 2]); } if (n1 < 0) { ep2_sub(r, r, table1[-n1 / 2]); } } /* Convert r to affine coordinates. */ ep2_norm(r, r); /* Free the precomputation table. */ for (i = 0; i < 1 << (EP_WIDTH - 2); i++) { ep2_free(table0[i]); ep2_free(table1[i]); } }