void pp_map_weilp_k12(fp12_t r, ep_t p, ep2_t q) { ep_t _p[1], t0[1]; ep2_t _q[1], t1[1]; fp12_t r0, r1; bn_t n; ep_null(_p[0]); ep_null(t0[1]); ep2_null(_q[0]); ep2_null(t1[1]); fp12_null(r0); fp12_null(r1); bn_null(n); TRY { ep_new(_p[0]); ep_new(t0[0]); ep2_new(_q[0]); ep2_new(t1[0]); fp12_new(r0); fp12_new(r1); bn_new(n); ep_norm(_p[0], p); ep2_norm(_q[0], q); ep_curve_get_ord(n); bn_sub_dig(n, n, 1); fp12_set_dig(r0, 1); fp12_set_dig(r1, 1); if (!ep_is_infty(_p[0]) && !ep2_is_infty(_q[0])) { pp_mil_lit_k12(r0, t0, _p, _q, 1, n); pp_mil_k12(r1, t1, _q, _p, 1, n); fp12_inv(r1, r1); fp12_mul(r0, r0, r1); fp12_inv(r1, r0); fp12_inv_uni(r0, r0); } fp12_mul(r, r0, r1); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep_free(_p[0]); ep_free(t0[0]); ep2_free(_q[0]); ep2_free(t1[0]); fp12_free(r0); fp12_free(r1); bn_free(n); } }
void fp12_write_bin(uint8_t *bin, int len, fp12_t a, int pack) { fp12_t t; fp12_null(t); TRY { fp12_new(t); if (pack) { if (len != 8 * FP_BYTES) { THROW(ERR_NO_BUFFER); } fp12_pck(t, a); fp2_write_bin(bin, 2 * FP_BYTES, a[0][1], 0); fp2_write_bin(bin + 2 * FP_BYTES, 2 * FP_BYTES, a[0][2], 0); fp2_write_bin(bin + 4 * FP_BYTES, 2 * FP_BYTES, a[1][0], 0); fp2_write_bin(bin + 6 * FP_BYTES, 2 * FP_BYTES, a[1][2], 0); } else { if (len != 12 * FP_BYTES) { THROW(ERR_NO_BUFFER); } fp6_write_bin(bin, 6 * FP_BYTES, a[0]); fp6_write_bin(bin + 6 * FP_BYTES, 6 * FP_BYTES, a[1]); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp12_free(t); } }
/** * Compute the final lines for optimal ate pairings. * * @param[out] r - the result. * @param[out] t - the resulting point. * @param[in] q - the first point of the pairing, in G_2. * @param[in] p - the second point of the pairing, in G_1. * @param[in] a - the loop parameter. */ static void pp_fin_k12_oatep(fp12_t r, ep2_t t, ep2_t q, ep_t p) { ep2_t q1, q2; fp12_t tmp; fp12_null(tmp); ep2_null(q1); ep2_null(q2); TRY { ep2_new(q1); ep2_new(q2); fp12_new(tmp); fp12_zero(tmp); fp2_set_dig(q1->z, 1); fp2_set_dig(q2->z, 1); ep2_frb(q1, q, 1); ep2_frb(q2, q, 2); ep2_neg(q2, q2); pp_add_k12(tmp, t, q1, p); fp12_mul_dxs(r, r, tmp); pp_add_k12(tmp, t, q2, p); fp12_mul_dxs(r, r, tmp); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp12_free(tmp); ep2_free(q1); ep2_free(q2); } }
/** * Compute the Miller loop for pairings of type G_2 x G_1 over the bits of a * given parameter. * * @param[out] r - the result. * @param[out] t - the resulting point. * @param[in] q - the first pairing argument in affine coordinates. * @param[in] p - the second pairing argument in affine coordinates. * @param[in] n - the number of pairings to evaluate. * @param[in] a - the loop parameter. */ static void pp_mil_k12(fp12_t r, ep2_t *t, ep2_t *q, ep_t *p, int m, bn_t a) { fp12_t l; ep_t _p[m]; int i, j; if (m == 0) { return; } fp12_null(l); TRY { fp12_new(l); for (j = 0; j < m; j++) { ep_null(_p[j]); ep_new(_p[j]); #if EP_ADD == BASIC ep_neg(_p[j], p[i]); #else fp_add(_p[j]->x, p[j]->x, p[j]->x); fp_add(_p[j]->x, _p[j]->x, p[j]->x); fp_neg(_p[j]->y, p[j]->y); #endif ep2_copy(t[j], q[j]); } fp12_zero(l); /* Precomputing. */ pp_dbl_k12(r, t[0], t[0], _p[0]); if (bn_get_bit(a, bn_bits(a) - 2)) { for (j = 0; j < m; j++) { pp_add_k12(l, t[j], q[j], p[j]); fp12_mul_dxs(r, r, l); } } for (i = bn_bits(a) - 3; i >= 0; i--) { fp12_sqr(r, r); for (j = 0; j < m; j++) { pp_dbl_k12(l, t[j], t[j], _p[j]); fp12_mul_dxs(r, r, l); if (bn_get_bit(a, i)) { pp_add_k12(l, t[j], q[j], p[j]); fp12_mul_dxs(r, r, l); } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp12_free(l); for (j = 0; j < m; j++) { ep_free(_p[j]); } } }
/** * Compute the Miller loop for pairings of type G_1 x G_2 over the bits of a * given parameter. * * @param[out] r - the result. * @param[out] t - the resulting point. * @param[in] p - the first pairing argument in affine coordinates. * @param[in] q - the second pairing argument in affine coordinates. * @param[in] n - the number of pairings to evaluate. * @param[in] a - the loop parameter. */ static void pp_mil_lit_k12(fp12_t r, ep_t *t, ep_t *p, ep2_t *q, int m, bn_t a) { fp12_t l; ep2_t _q[m]; int j; fp12_null(l); TRY { fp12_new(l); for (j = 0; j < m; j++) { ep2_null(_q[j]); ep2_new(_q[j]); ep_copy(t[j], p[j]); ep2_neg(_q[j], q[j]); } fp12_zero(l); for (int i = bn_bits(a) - 2; i >= 0; i--) { fp12_sqr(r, r); for (j = 0; j < m; j++) { pp_dbl_lit_k12(l, t[j], t[j], _q[j]); fp12_mul(r, r, l); if (bn_get_bit(a, i)) { pp_add_lit_k12(l, t[j], p[j], q[j]); fp12_mul(r, r, l); } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp12_free(l); for (j = 0; j < m; j++) { ep2_free(_q[j]); } } }
void pp_map_sim_weilp_k12(fp12_t r, ep_t *p, ep2_t *q, int m) { ep_t _p[m], t0[m]; ep2_t _q[m], t1[m]; fp12_t r0, r1; bn_t n; int i, j; fp12_null(r0); fp12_null(r1); bn_null(r); TRY { fp12_new(r0); fp12_new(r1); bn_new(n); for (i = 0; i < m; i++) { ep_null(_p[i]); ep_null(t0[i]); ep2_null(_q[i]); ep2_null(t1[i]); ep_new(_p[i]); ep_new(t0[i]); ep2_new(_q[i]); ep2_new(t1[i]); } j = 0; for (i = 0; i < m; i++) { if (!ep_is_infty(p[i]) && !ep2_is_infty(q[i])) { ep_norm(_p[j], p[i]); ep2_norm(_q[j++], q[i]); } } ep_curve_get_ord(n); bn_sub_dig(n, n, 1); fp12_set_dig(r0, 1); fp12_set_dig(r1, 1); if (j > 0) { pp_mil_lit_k12(r0, t0, _p, _q, j, n); pp_mil_k12(r1, t1, _q, _p, j, n); fp12_inv(r1, r1); fp12_mul(r0, r0, r1); fp12_inv(r1, r0); fp12_inv_uni(r0, r0); } fp12_mul(r, r0, r1); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp12_free(r0); fp12_free(r1); bn_free(n); for (i = 0; i < m; i++) { ep_free(_p[i]); ep_free(t0[i]); ep2_free(_q[i]); ep2_free(t1[i]); } } }
/** * Compute the Miller loop for pairings of type G_2 x G_1 over the bits of a * given parameter represented in sparse form. * * @param[out] r - the result. * @param[out] t - the resulting point. * @param[in] q - the vector of first arguments in affine coordinates. * @param[in] p - the vector of second arguments in affine coordinates. * @param[in] n - the number of pairings to evaluate. * @param[in] s - the loop parameter in sparse form. * @paramin] len - the length of the loop parameter. */ static void pp_mil_sps_k12(fp12_t r, ep2_t *t, ep2_t *q, ep_t *p, int m, int *s, int len) { fp12_t l; ep_t _p[m]; ep2_t _q[m]; int i, j; if (m == 0) { return; } fp12_null(l); TRY { fp12_new(l); fp12_zero(l); for (j = 0; j < m; j++) { ep_null(_p[j]); ep2_null(_q[j]); ep_new(_p[j]); ep2_new(_q[j]); ep2_copy(t[j], q[j]); ep2_neg(_q[j], q[j]); #if EP_ADD == BASIC ep_neg(_p[j], p[j]); #else fp_add(_p[j]->x, p[j]->x, p[j]->x); fp_add(_p[j]->x, _p[j]->x, p[j]->x); fp_neg(_p[j]->y, p[j]->y); #endif } pp_dbl_k12(r, t[0], t[0], _p[0]); for (j = 1; j < m; j++) { pp_dbl_k12(l, t[j], t[j], _p[j]); fp12_mul_dxs(r, r, l); } if (s[len - 2] > 0) { for (j = 0; j < m; j++) { pp_add_k12(l, t[j], q[j], p[j]); fp12_mul_dxs(r, r, l); } } if (s[len - 2] < 0) { for (j = 0; j < m; j++) { pp_add_k12(l, t[j], _q[j], p[j]); fp12_mul_dxs(r, r, l); } } for (i = len - 3; i >= 0; i--) { fp12_sqr(r, r); for (j = 0; j < m; j++) { pp_dbl_k12(l, t[j], t[j], _p[j]); fp12_mul_dxs(r, r, l); if (s[i] > 0) { pp_add_k12(l, t[j], q[j], p[j]); fp12_mul_dxs(r, r, l); } if (s[i] < 0) { pp_add_k12(l, t[j], _q[j], p[j]); fp12_mul_dxs(r, r, l); } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp12_free(l); for (j = 0; j < m; j++) { ep_free(_p[j]); ep2_free(_q[j]); } } }
/** * Computes the final exponentiation of a pairing defined over a Barreto-Naehrig * curve. * * @param[out] c - the result. * @param[in] a - the extension field element to exponentiate. */ static void pp_exp_bn(fp12_t c, fp12_t a) { fp12_t t0, t1, t2, t3; int l = MAX_TERMS + 1, b[MAX_TERMS + 1]; bn_t x; fp12_null(t0); fp12_null(t1); fp12_null(t2); fp12_null(t3); bn_null(x); TRY { fp12_new(t0); fp12_new(t1); fp12_new(t2); fp12_new(t3); bn_new(x); /* * New final exponentiation following Fuentes-Castañeda, Knapp and * Rodríguez-Henríquez: Fast Hashing to G_2. */ fp_param_get_var(x); fp_param_get_sps(b, &l); /* First, compute m = f^(p^6 - 1)(p^2 + 1). */ fp12_conv_cyc(c, a); /* Now compute m^((p^4 - p^2 + 1) / r). */ /* t0 = m^2x. */ fp12_exp_cyc_sps(t0, c, b, l); fp12_sqr_cyc(t0, t0); /* t1 = m^6x. */ fp12_sqr_cyc(t1, t0); fp12_mul(t1, t1, t0); /* t2 = m^6x^2. */ fp12_exp_cyc_sps(t2, t1, b, l); /* t3 = m^12x^3. */ fp12_sqr_cyc(t3, t2); fp12_exp_cyc_sps(t3, t3, b, l); if (bn_sign(x) == BN_NEG) { fp12_inv_uni(t0, t0); fp12_inv_uni(t1, t1); fp12_inv_uni(t3, t3); } /* t3 = a = m^12x^3 * m^6x^2 * m^6x. */ fp12_mul(t3, t3, t2); fp12_mul(t3, t3, t1); /* t0 = b = 1/(m^2x) * t3. */ fp12_inv_uni(t0, t0); fp12_mul(t0, t0, t3); /* Compute t2 * t3 * m * b^p * a^p^2 * [b * 1/m]^p^3. */ fp12_mul(t2, t2, t3); fp12_mul(t2, t2, c); fp12_inv_uni(c, c); fp12_mul(c, c, t0); fp12_frb(c, c, 3); fp12_mul(c, c, t2); fp12_frb(t0, t0, 1); fp12_mul(c, c, t0); fp12_frb(t3, t3, 2); fp12_mul(c, c, t3); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp12_free(t0); fp12_free(t1); fp12_free(t2); fp12_free(t3); bn_free(x); } }
/** * Computes the final exponentiation of a pairing defined over a * Barreto-Lynn-Scott curve. * * @param[out] c - the result. * @param[in] a - the extension field element to exponentiate. */ static void pp_exp_b12(fp12_t c, fp12_t a) { fp12_t t[10]; bn_t x; int l = MAX_TERMS + 1, b[MAX_TERMS + 1]; bn_null(x); TRY { for (int i = 0; i < 10; i++) { fp12_null(t[i]); fp12_new(t[i]); } bn_new(x); fp_param_get_var(x); fp_param_get_sps(b, &l); /* First, compute m^(p^6 - 1)(p^2 + 1). */ fp12_conv_cyc(c, a); /* v0 = f^-1. */ fp12_inv_uni(t[0], c); /* v1 = f^-2. */ fp12_sqr_cyc(t[1], t[0]); /* v2 = f^x. */ fp12_exp_cyc_sps(t[2], c, b, l); if (bn_sign(x) == BN_NEG) { fp12_inv_uni(t[2], t[2]); } /* v3 = f^2x. */ fp12_sqr_cyc(t[3], t[2]); /* v4 = f^(x - 2). */ fp12_mul(t[4], t[2], t[1]); /* v5 = f^(x^2 - 2x). */ fp12_exp_cyc_sps(t[5], t[4], b, l); if (bn_sign(x) == BN_NEG) { fp12_inv_uni(t[5], t[5]); } /* v6 = f^(x^3 - 2x^2). */ fp12_exp_cyc_sps(t[6], t[5], b, l); if (bn_sign(x) == BN_NEG) { fp12_inv_uni(t[6], t[6]); } /* v7 = f^(x^4 - 2x^3 + 2x). */ fp12_exp_cyc_sps(t[7], t[6], b, l); if (bn_sign(x) == BN_NEG) { fp12_inv_uni(t[7], t[7]); } fp12_mul(t[7], t[7], t[3]); /* v8 = f^(x^5 - 2x^4 + 2x^2). */ fp12_exp_cyc_sps(t[8], t[7], b, l); if (bn_sign(x) == BN_NEG) { fp12_inv_uni(t[8], t[8]); } /* v7 = f^(x^4 - 2x^3 + 2x - 1)^p. */ fp12_mul(t[7], t[7], t[0]); fp12_frb(t[7], t[7], 1); /* v6 = f^(x^3 - 2x^2 + x)^p^2. */ fp12_mul(t[6], t[6], t[2]); fp12_frb(t[6], t[6], 2); /* v5 = f^(x^2 - 2x + 1)^p^3. */ fp12_mul(t[5], t[5], c); fp12_frb(t[5], t[5], 1); fp12_frb(t[5], t[5], 2); /* v4 = f^(2 - x). */ fp12_inv_uni(t[4], t[4]); /* Now compute f * v4 * v5 * v6 * v7 * v8. */ fp12_mul(c, c, t[4]); fp12_mul(c, c, t[5]); fp12_mul(c, c, t[6]); fp12_mul(c, c, t[7]); fp12_mul(c, c, t[8]); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (int i = 0; i < 9; i++) { fp12_free(t[i]); } bn_free(x); } }