void ep2_frb(ep2_t r, ep2_t p, int i) { switch (i) { case 0: ep2_copy(r, p); break; case 1: fp2_frb(r->x, p->x, 1); fp2_frb(r->y, p->y, 1); if (ep2_curve_is_twist() == EP_MTYPE) { fp2_mul_frb(r->x, r->x, 1, 4); fp2_mul_art(r->x, r->x); fp2_mul_art(r->y, r->y); } else { fp2_mul_frb(r->x, r->x, 1, 2); } fp2_mul_frb(r->y, r->y, 1, 3); break; case 2: if (ep2_curve_is_twist() == EP_MTYPE) { fp2_mul_frb(r->x, p->x, 2, 4); } else { fp2_mul_frb(r->x, p->x, 2, 2); } fp2_neg(r->y, p->y); break; case 3: if (ep2_curve_is_twist() == EP_MTYPE) { fp2_frb(r->x, p->x, 1); fp2_frb(r->y, p->y, 1); fp2_mul_frb(r->x, r->x, 1, 4); fp2_mul_frb(r->x, r->x, 2, 4); fp2_mul_art(r->x, r->x); fp2_mul_frb(r->y, r->y, 1, 3); fp2_mul_art(r->y, r->y); fp2_neg(r->y, r->y); } else { fp2_frb(r->x, p->x, 1); fp2_mul_frb(r->x, r->x, 3, 2); fp_neg(r->y[0], p->y[0]); fp_copy(r->y[1], p->y[1]); fp2_mul_frb(r->y, r->y, 1, 3); } break; } r->norm = 1; fp_set_dig(r->z[0], 1); fp_zero(r->z[1]); }
void ep2_frb(ep2_t r, ep2_t p, int i) { ep2_copy(r, p); switch (i) { case 1: fp2_frb(r->x, r->x, 1); fp2_frb(r->y, r->y, 1); fp2_frb(r->z, r->z, 1); if (ep2_curve_is_twist() == EP_MTYPE) { fp2_mul_frb(r->x, r->x, 1, 4); fp2_mul_art(r->x, r->x); fp2_mul_art(r->y, r->y); } else { fp2_mul_frb(r->x, r->x, 1, 2); } fp2_mul_frb(r->y, r->y, 1, 3); break; case 2: if (ep2_curve_is_twist() == EP_MTYPE) { fp2_mul_frb(r->x, r->x, 2, 4); } else { fp2_mul_frb(r->x, r->x, 2, 2); } fp2_neg(r->y, r->y); break; case 3: if (ep2_curve_is_twist() == EP_MTYPE) { fp2_frb(r->x, r->x, 1); fp2_frb(r->y, r->y, 1); fp2_frb(r->z, r->z, 1); fp2_mul_frb(r->x, r->x, 1, 4); fp2_mul_frb(r->x, r->x, 2, 4); fp2_mul_art(r->x, r->x); fp2_mul_frb(r->y, r->y, 1, 3); fp2_mul_art(r->y, r->y); fp2_neg(r->y, r->y); } else { fp2_frb(r->x, r->x, 1); fp2_mul_frb(r->x, r->x, 3, 2); fp_neg(r->y[0], r->y[0]); fp_copy(r->y[1], r->y[1]); fp2_mul_frb(r->y, r->y, 1, 3); } break; } }
/** * Computes the constantes required for evaluating Frobenius maps. */ static void fp2_calc() { bn_t e; fp2_t t0; fp2_t t1; ctx_t *ctx = core_get(); bn_null(e); fp2_null(t0); fp2_null(t1); TRY { bn_new(e); fp2_new(t0); fp2_new(t1); fp2_zero(t0); fp_set_dig(t0[0], 1); fp2_mul_nor(t0, t0); e->used = FP_DIGS; dv_copy(e->dp, fp_prime_get(), FP_DIGS); bn_sub_dig(e, e, 1); bn_div_dig(e, e, 6); fp2_exp(t0, t0, e); #if ALLOC == AUTO fp2_copy(ctx->fp2_p[0], t0); fp2_sqr(ctx->fp2_p[1], ctx->fp2_p[0]); fp2_mul(ctx->fp2_p[2], ctx->fp2_p[1], ctx->fp2_p[0]); fp2_sqr(ctx->fp2_p[3], ctx->fp2_p[1]); fp2_mul(ctx->fp2_p[4], ctx->fp2_p[3], ctx->fp2_p[0]); #else fp_copy(ctx->fp2_p[0][0], t0[0]); fp_copy(ctx->fp2_p[0][1], t0[1]); fp2_sqr(t1, t0); fp_copy(ctx->fp2_p[1][0], t1[0]); fp_copy(ctx->fp2_p[1][1], t1[1]); fp2_mul(t1, t1, t0); fp_copy(ctx->fp2_p[2][0], t1[0]); fp_copy(ctx->fp2_p[2][1], t1[1]); fp2_sqr(t1, t0); fp2_sqr(t1, t1); fp_copy(ctx->fp2_p[3][0], t1[0]); fp_copy(ctx->fp2_p[3][1], t1[1]); fp2_mul(t1, t1, t0); fp_copy(ctx->fp2_p[4][0], t1[0]); fp_copy(ctx->fp2_p[4][1], t1[1]); #endif fp2_frb(t1, t0, 1); fp2_mul(t0, t1, t0); fp_copy(ctx->fp2_p2[0], t0[0]); fp_sqr(ctx->fp2_p2[1], ctx->fp2_p2[0]); fp_mul(ctx->fp2_p2[2], ctx->fp2_p2[1], ctx->fp2_p2[0]); fp_sqr(ctx->fp2_p2[3], ctx->fp2_p2[1]); for (int i = 0; i < 5; i++) { fp_mul(ctx->fp2_p3[i][0], ctx->fp2_p2[i % 3], ctx->fp2_p[i][0]); fp_mul(ctx->fp2_p3[i][1], ctx->fp2_p2[i % 3], ctx->fp2_p[i][1]); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(e); fp2_free(t0); fp2_free(t1); } }