void pp_map_weilp_k2(fp2_t r, ep_t p, ep_t q) { ep_t _p[1], _q[1], t0[1], t1[1]; fp2_t r0, r1; bn_t n; ep_null(_p[0]); ep_null(_q[0]); ep_null(t0[0]); ep_null(t1[0]); fp2_null(r0); fp2_null(r1); bn_null(n); TRY { ep_new(_p[0]); ep_new(_q[0]); ep_new(t0[0]); ep_new(t1[0]); fp2_new(r0); fp2_new(r1); bn_new(n); ep_norm(_p[0], p); ep_norm(_q[0], q); ep_curve_get_ord(n); /* Since p has order n, we do not have to perform last iteration. */ bn_sub_dig(n, n, 1); fp2_set_dig(r0, 1); fp2_set_dig(r1, 1); if (!ep_is_infty(_p[0]) && !ep_is_infty(_q[0])) { pp_mil_lit_k2(r0, t0, _p, _q, 1, n); pp_mil_k2(r1, t1, _q, _p, 1, n); fp2_inv(r1, r1); fp2_mul(r0, r0, r1); fp2_inv(r1, r0); fp2_inv_uni(r0, r0); } fp2_mul(r, r0, r1); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep_free(_p[0]); ep_free(_q[0]); ep_free(t0[0]); ep_free(t1[0]); fp2_free(r0); fp2_free(r1); bn_free(n); } }
/** * Doubles a point represented in affine coordinates on an ordinary prime * elliptic curve. * * @param[out] r - the result. * @param[out] s - the resulting slope. * @param[in] p - the point to double. */ static void ep2_dbl_basic_imp(ep2_t r, fp2_t s, ep2_t p) { fp2_t t0, t1, t2; fp2_null(t0); fp2_null(t1); fp2_null(t2); TRY { fp2_new(t0); fp2_new(t1); fp2_new(t2); /* t0 = 1/(2 * y1). */ fp2_dbl(t0, p->y); fp2_inv(t0, t0); /* t1 = 3 * x1^2 + a. */ fp2_sqr(t1, p->x); fp2_copy(t2, t1); fp2_dbl(t1, t1); fp2_add(t1, t1, t2); ep2_curve_get_a(t2); fp2_add(t1, t1, t2); /* t1 = (3 * x1^2 + a)/(2 * y1). */ fp2_mul(t1, t1, t0); if (s != NULL) { fp2_copy(s, t1); } /* t2 = t1^2. */ fp2_sqr(t2, t1); /* x3 = t1^2 - 2 * x1. */ fp2_dbl(t0, p->x); fp2_sub(t0, t2, t0); /* y3 = t1 * (x1 - x3) - y1. */ fp2_sub(t2, p->x, t0); fp2_mul(t1, t1, t2); fp2_sub(r->y, t1, p->y); fp2_copy(r->x, t0); fp2_copy(r->z, p->z); r->norm = 1; } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(t0); fp2_free(t1); fp2_free(t2); } }
void fp6_inv(fp6_t c, fp6_t a) { fp2_t v0; fp2_t v1; fp2_t v2; fp2_t t0; fp2_null(v0); fp2_null(v1); fp2_null(v2); fp2_null(t0); TRY { fp2_new(v0); fp2_new(v1); fp2_new(v2); fp2_new(t0); /* v0 = a_0^2 - E * a_1 * a_2. */ fp2_sqr(t0, a[0]); fp2_mul(v0, a[1], a[2]); fp2_mul_nor(v2, v0); fp2_sub(v0, t0, v2); /* v1 = E * a_2^2 - a_0 * a_1. */ fp2_sqr(t0, a[2]); fp2_mul_nor(v2, t0); fp2_mul(v1, a[0], a[1]); fp2_sub(v1, v2, v1); /* v2 = a_1^2 - a_0 * a_2. */ fp2_sqr(t0, a[1]); fp2_mul(v2, a[0], a[2]); fp2_sub(v2, t0, v2); fp2_mul(t0, a[1], v2); fp2_mul_nor(c[1], t0); fp2_mul(c[0], a[0], v0); fp2_mul(t0, a[2], v1); fp2_mul_nor(c[2], t0); fp2_add(t0, c[0], c[1]); fp2_add(t0, t0, c[2]); fp2_inv(t0, t0); fp2_mul(c[0], v0, t0); fp2_mul(c[1], v1, t0); fp2_mul(c[2], v2, t0); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(v0); fp2_free(v1); fp2_free(v2); fp2_free(t0); } }
/** * Normalizes a point represented in projective coordinates. * * @param r - the result. * @param p - the point to normalize. */ void pp_norm_imp(ep2_t r, ep2_t p) { fp2_inv(r->z, p->z); fp2_mul(r->x, p->x, r->z); fp2_mul(r->y, p->y, r->z); fp_zero(r->z[0]); fp_zero(r->z[1]); fp_set_dig(r->z[0], 1); r->norm = 1; }
void fp2_inv_sim(fp2_t *c, fp2_t *a, int n) { int i; fp2_t u, t[n]; for (i = 0; i < n; i++) { fp2_null(t[i]); } fp2_null(u); TRY { for (i = 0; i < n; i++) { fp2_new(t[i]); } fp2_new(u); fp2_copy(c[0], a[0]); fp2_copy(t[0], a[0]); for (i = 1; i < n; i++) { fp2_copy(t[i], a[i]); fp2_mul(c[i], c[i - 1], t[i]); } fp2_inv(u, c[n - 1]); for (i = n - 1; i > 0; i--) { fp2_mul(c[i], c[i - 1], u); fp2_mul(u, u, t[i]); } fp2_copy(c[0], u); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 0; i < n; i++) { fp2_free(t[i]); } fp2_free(u); } }
/** * Doubles a point represented in affine coordinates on an ordinary prime * elliptic curve. * * @param[out] r - the result. * @param[out] s - the resulting slope. * @param[in] p - the point to double. */ static void ep2_dbl_basic_imp(ep2_t r, fp2_t s, ep2_t p) { fp2_t t0, t1, t2; fp2_null(t0); fp2_null(t1); fp2_null(t2); TRY { fp2_new(t0); fp2_new(t1); fp2_new(t2); /* t0 = 1/(2 * y1). */ fp2_dbl(t0, p->y); fp2_inv(t0, t0); /* t1 = 3 * x1^2 + a. */ fp2_sqr(t1, p->x); fp2_copy(t2, t1); fp2_dbl(t1, t1); fp2_add(t1, t1, t2); if (ep2_curve_is_twist()) { switch (ep_curve_opt_a()) { case OPT_ZERO: break; case OPT_ONE: fp_set_dig(t2[0], 1); fp2_mul_art(t2, t2); fp2_mul_art(t2, t2); fp2_add(t1, t1, t2); break; case OPT_DIGIT: fp_set_dig(t2[0], ep_curve_get_a()[0]); fp2_mul_art(t2, t2); fp2_mul_art(t2, t2); fp2_add(t1, t1, t2); break; default: fp_copy(t2[0], ep_curve_get_a()); fp_zero(t2[1]); fp2_mul_art(t2, t2); fp2_mul_art(t2, t2); fp2_add(t1, t1, t2); break; } } /* t1 = (3 * x1^2 + a)/(2 * y1). */ fp2_mul(t1, t1, t0); if (s != NULL) { fp2_copy(s, t1); } /* t2 = t1^2. */ fp2_sqr(t2, t1); /* x3 = t1^2 - 2 * x1. */ fp2_dbl(t0, p->x); fp2_sub(t0, t2, t0); /* y3 = t1 * (x1 - x3) - y1. */ fp2_sub(t2, p->x, t0); fp2_mul(t1, t1, t2); fp2_sub(r->y, t1, p->y); fp2_copy(r->x, t0); fp2_copy(r->z, p->z); r->norm = 1; } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(t0); fp2_free(t1); fp2_free(t2); } }
/** * Adds two points represented in affine coordinates on an ordinary prime * elliptic curve. * * @param r - the result. * @param s - the resulting slope. * @param p - the first point to add. * @param q - the second point to add. */ static void ep2_add_basic_imp(ep2_t r, fp2_t s, ep2_t p, ep2_t q) { fp2_t t0, t1, t2; fp2_null(t0); fp2_null(t1); fp2_null(t2); TRY { fp2_new(t0); fp2_new(t1); fp2_new(t2); /* t0 = x2 - x1. */ fp2_sub(t0, q->x, p->x); /* t1 = y2 - y1. */ fp2_sub(t1, q->y, p->y); /* If t0 is zero. */ if (fp2_is_zero(t0)) { if (fp2_is_zero(t1)) { /* If t1 is zero, q = p, should have doubled. */ ep2_dbl_basic(r, p); } else { /* If t1 is not zero and t0 is zero, q = -p and r = infty. */ ep2_set_infty(r); } } else { /* t2 = 1/(x2 - x1). */ fp2_inv(t2, t0); /* t2 = lambda = (y2 - y1)/(x2 - x1). */ fp2_mul(t2, t1, t2); /* x3 = lambda^2 - x2 - x1. */ fp2_sqr(t1, t2); fp2_sub(t0, t1, p->x); fp2_sub(t0, t0, q->x); /* y3 = lambda * (x1 - x3) - y1. */ fp2_sub(t1, p->x, t0); fp2_mul(t1, t2, t1); fp2_sub(r->y, t1, p->y); fp2_copy(r->x, t0); fp2_copy(r->z, p->z); if (s != NULL) { fp2_copy(s, t2); } r->norm = 1; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(t0); fp2_free(t1); fp2_free(t2); } }
void pp_map_sim_weilp_k2(fp2_t r, ep_t *p, ep_t *q, int m) { ep_t _p[m], _q[m], t0[m], t1[m]; fp2_t r0, r1; bn_t n; int i, j; fp2_null(r0); fp2_null(r1); bn_null(r); TRY { fp2_new(r0); fp2_new(r1); bn_new(n); for (i = 0; i < m; i++) { ep_null(_p[i]); ep_null(_q[i]); ep_null(t0[i]); ep_null(t1[i]); ep_new(_p[i]); ep_new(_q[i]); ep_new(t0[i]); ep_new(t1[i]); } j = 0; for (i = 0; i < m; i++) { if (!ep_is_infty(p[i]) && !ep_is_infty(q[i])) { ep_norm(_p[j], p[i]); ep_norm(_q[j++], q[i]); } } ep_curve_get_ord(n); bn_sub_dig(n, n, 1); fp2_set_dig(r0, 1); fp2_set_dig(r1, 1); if (j > 0) { pp_mil_lit_k2(r0, t0, _p, _q, j, n); pp_mil_k2(r1, t1, _q, _p, j, n); fp2_inv(r1, r1); fp2_mul(r0, r0, r1); fp2_inv(r1, r0); fp2_inv_uni(r0, r0); } fp2_mul(r, r0, r1); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(r0); fp2_free(r1); bn_free(n); for (i = 0; i < m; i++) { ep_free(_p[i]); ep_free(_q[i]); ep_free(t0[i]); ep_free(t1[i]); } } }