int fp3_srt(fp3_t c, fp3_t a) { int r = 0; fp3_t t0, t1, t2, t3; bn_t e; fp3_null(t0); fp3_null(t1); fp3_null(t2); fp3_null(t3); bn_null(e); TRY { fp3_new(t0); fp3_new(t1); fp3_new(t2); fp3_new(t3); bn_new(e); fp3_dbl(t3, a); fp3_frb(t0, t3, 1); fp3_sqr(t1, t0); fp3_mul(t2, t1, t0); fp3_mul(t1, t1, t2); fp3_frb(t0, t0, 1); fp3_mul(t3, t3, t1); fp3_mul(t0, t0, t3); e->used = FP_DIGS; dv_copy(e->dp, fp_prime_get(), FP_DIGS); bn_sub_dig(e, e, 5); bn_div_dig(e, e, 8); fp3_exp(t0, t0, e); fp3_mul(t0, t0, t2); fp3_sqr(t1, t0); fp3_mul(t1, t1, a); fp3_dbl(t1, t1); fp3_mul(t0, t0, a); fp_sub_dig(t1[0], t1[0], 1); fp3_mul(c, t0, t1); fp3_sqr(t0, c); if (fp3_cmp(t0, a) == CMP_EQ) { r = 1; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp3_free(t0); fp3_free(t1); fp3_free(t2); fp3_free(t3); bn_free(e); } return r; }
void fp3_inv_sim(fp3_t * c, fp3_t * a, int n) { int i; fp3_t u, t[n]; for (i = 0; i < n; i++) { fp3_null(t[i]); } fp3_null(u); TRY { for (i = 0; i < n; i++) { fp3_new(t[i]); } fp3_new(u); fp3_copy(c[0], a[0]); fp3_copy(t[0], a[0]); for (i = 1; i < n; i++) { fp3_copy(t[i], a[i]); fp3_mul(c[i], c[i - 1], t[i]); } fp3_inv(u, c[n - 1]); for (i = n - 1; i > 0; i--) { fp3_mul(c[i], c[i - 1], u); fp3_mul(u, u, t[i]); } fp3_copy(c[0], u); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 0; i < n; i++) { fp3_free(t[i]); } fp3_free(u); } }
/** * Computes the constants required for evaluating Frobenius maps. */ static void fp3_calc() { bn_t e; fp3_t t0, t1, t2; ctx_t *ctx = core_get(); bn_null(e); fp3_null(t0); fp3_null(t1); fp3_null(t2); TRY { bn_new(e); fp3_new(t0); fp3_new(t1); fp3_new(t2); fp_set_dig(ctx->fp3_base[0], -fp_prime_get_cnr()); fp_neg(ctx->fp3_base[0], ctx->fp3_base[0]); e->used = FP_DIGS; dv_copy(e->dp, fp_prime_get(), FP_DIGS); bn_sub_dig(e, e, 1); bn_div_dig(e, e, 3); fp_exp(ctx->fp3_base[0], ctx->fp3_base[0], e); fp_sqr(ctx->fp3_base[1], ctx->fp3_base[0]); fp3_zero(t0); fp_set_dig(t0[1], 1); dv_copy(e->dp, fp_prime_get(), FP_DIGS); bn_sub_dig(e, e, 1); bn_div_dig(e, e, 6); /* t0 = u^((p-1)/6). */ fp3_exp(t0, t0, e); fp_copy(ctx->fp3_p[0], t0[2]); fp3_sqr(t1, t0); fp_copy(ctx->fp3_p[1], t1[1]); fp3_mul(t2, t1, t0); fp_copy(ctx->fp3_p[2], t2[0]); fp3_sqr(t2, t1); fp_copy(ctx->fp3_p[3], t2[2]); fp3_mul(t2, t2, t0); fp_copy(ctx->fp3_p[4], t2[1]); fp_mul(ctx->fp3_p2[0], ctx->fp3_p[0], ctx->fp3_base[1]); fp_mul(t0[0], ctx->fp3_p2[0], ctx->fp3_p[0]); fp_neg(ctx->fp3_p2[0], t0[0]); for (int i = -1; i > fp_prime_get_cnr(); i--) { fp_sub(ctx->fp3_p2[0], ctx->fp3_p2[0], t0[0]); } fp_mul(ctx->fp3_p2[1], ctx->fp3_p[1], ctx->fp3_base[0]); fp_mul(ctx->fp3_p2[1], ctx->fp3_p2[1], ctx->fp3_p[1]); fp_sqr(ctx->fp3_p2[2], ctx->fp3_p[2]); fp_mul(ctx->fp3_p2[3], ctx->fp3_p[3], ctx->fp3_base[1]); fp_mul(t0[0], ctx->fp3_p2[3], ctx->fp3_p[3]); fp_neg(ctx->fp3_p2[3], t0[0]); for (int i = -1; i > fp_prime_get_cnr(); i--) { fp_sub(ctx->fp3_p2[3], ctx->fp3_p2[3], t0[0]); } fp_mul(ctx->fp3_p2[4], ctx->fp3_p[4], ctx->fp3_base[0]); fp_mul(ctx->fp3_p2[4], ctx->fp3_p2[4], ctx->fp3_p[4]); fp_mul(ctx->fp3_p3[0], ctx->fp3_p[0], ctx->fp3_base[0]); fp_mul(t0[0], ctx->fp3_p3[0], ctx->fp3_p2[0]); fp_neg(ctx->fp3_p3[0], t0[0]); for (int i = -1; i > fp_prime_get_cnr(); i--) { fp_sub(ctx->fp3_p3[0], ctx->fp3_p3[0], t0[0]); } fp_mul(ctx->fp3_p3[1], ctx->fp3_p[1], ctx->fp3_base[1]); fp_mul(t0[0], ctx->fp3_p3[1], ctx->fp3_p2[1]); fp_neg(ctx->fp3_p3[1], t0[0]); for (int i = -1; i > fp_prime_get_cnr(); i--) { fp_sub(ctx->fp3_p3[1], ctx->fp3_p3[1], t0[0]); } fp_mul(ctx->fp3_p3[2], ctx->fp3_p[2], ctx->fp3_p2[2]); fp_mul(ctx->fp3_p3[3], ctx->fp3_p[3], ctx->fp3_base[0]); fp_mul(t0[0], ctx->fp3_p3[3], ctx->fp3_p2[3]); fp_neg(ctx->fp3_p3[3], t0[0]); for (int i = -1; i > fp_prime_get_cnr(); i--) { fp_sub(ctx->fp3_p3[3], ctx->fp3_p3[3], t0[0]); } fp_mul(ctx->fp3_p3[4], ctx->fp3_p[4], ctx->fp3_base[1]); fp_mul(t0[0], ctx->fp3_p3[4], ctx->fp3_p2[4]); fp_neg(ctx->fp3_p3[4], t0[0]); for (int i = -1; i > fp_prime_get_cnr(); i--) { fp_sub(ctx->fp3_p3[4], ctx->fp3_p3[4], t0[0]); } for (int i = 0; i < 5; i++) { fp_mul(ctx->fp3_p4[i], ctx->fp3_p[i], ctx->fp3_p3[i]); fp_mul(ctx->fp3_p5[i], ctx->fp3_p2[i], ctx->fp3_p3[i]); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(e); fp3_free(t0); fp3_free(t1); fp3_free(t2); } }