void fp12_pck(fp12_t c, fp12_t a) { fp12_copy(c, a); if (fp12_test_cyc(c)) { fp2_zero(c[0][0]); fp2_zero(c[1][1]); } }
void ep2_read_bin(ep2_t a, uint8_t *bin, int len) { if (len == 1) { if (bin[0] == 0) { ep2_set_infty(a); return; } else { THROW(ERR_NO_BUFFER); return; } } if (len != (2 * FP_BYTES + 1) && len != (4 * FP_BYTES + 1)) { THROW(ERR_NO_BUFFER); return; } a->norm = 1; fp_set_dig(a->z[0], 1); fp_zero(a->z[1]); fp2_read_bin(a->x, bin + 1, 2 * FP_BYTES); if (len == 2 * FP_BYTES + 1) { switch(bin[0]) { case 2: fp2_zero(a->y); break; case 3: fp2_zero(a->y); fp_set_bit(a->y[0], 0, 1); fp_zero(a->y[1]); break; default: THROW(ERR_NO_VALID); break; } ep2_upk(a, a); } if (len == 4 * FP_BYTES + 1) { if (bin[0] == 4) { fp2_read_bin(a->y, bin + 2 * FP_BYTES + 1, 2 * FP_BYTES); } else { THROW(ERR_NO_VALID); } } }
void fp12_read_bin(fp12_t a, uint8_t *bin, int len) { if (len != 8 * FP_BYTES && len != 12 * FP_BYTES) { THROW(ERR_NO_BUFFER); } if (len == 8 * FP_BYTES) { fp2_zero(a[0][0]); fp2_read_bin(a[0][1], bin, 2 * FP_BYTES); fp2_read_bin(a[0][2], bin + 2 * FP_BYTES, 2 * FP_BYTES); fp2_read_bin(a[1][0], bin + 4 * FP_BYTES, 2 * FP_BYTES); fp2_zero(a[1][1]); fp2_read_bin(a[1][2], bin + 6 * FP_BYTES, 2 * FP_BYTES); fp12_back_cyc(a, a); } if (len == 12 * FP_BYTES) { fp6_read_bin(a[0], bin, 6 * FP_BYTES); fp6_read_bin(a[1], bin + 6 * FP_BYTES, 6 * FP_BYTES); } }
/** * 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] p - the first pairing argument in affine coordinates. * @param[in] q - the second pairing argument in affine coordinates. * @param[in] m - the number of pairings to evaluate. * @param[in] a - the loop parameter. */ static void pp_mil_k2(fp2_t r, ep_t *t, ep_t *p, ep_t *q, int m, bn_t a) { fp2_t l; ep_t _q[m]; int i, j; fp2_null(l); TRY { fp2_new(l); for (j = 0; j < m; j++) { ep_null(_q[j]); ep_new(_q[j]); ep_copy(t[j], p[j]); ep_neg(_q[j], q[j]); } fp2_zero(l); for (i = bn_bits(a) - 2; i >= 0; i--) { fp2_sqr(r, r); for (j = 0; j < m; j++) { pp_dbl_k2(l, t[j], t[j], _q[j]); fp2_mul(r, r, l); if (bn_get_bit(a, i)) { pp_add_k2(l, t[j], p[j], q[j]); fp2_mul(r, r, l); } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(l); for (j = 0; j < m; j++) { ep_free(_q[j]); } } }
/** * 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); } }
void fp6_zero(fp6_t a) { fp2_zero(a[0]); fp2_zero(a[1]); fp2_zero(a[2]); }
void ep2_set_infty(ep2_t p) { fp2_zero(p->x); fp2_zero(p->y); fp2_zero(p->z); }
void ep2_curve_set_twist(int type) { char str[2 * FP_BYTES + 1]; ctx_t *ctx = core_get(); ep2_t g; fp2_t a; fp2_t b; bn_t r; ep2_null(g); fp2_null(a); fp2_null(b); bn_null(r); ctx->ep2_is_twist = 0; if (type == EP_MTYPE || type == EP_DTYPE) { ctx->ep2_is_twist = type; } else { return; } TRY { ep2_new(g); fp2_new(a); fp2_new(b); bn_new(r); switch (ep_param_get()) { #if FP_PRIME == 158 case BN_P158: ASSIGN(BN_P158); break; #elif FP_PRIME == 254 case BN_P254: ASSIGN(BN_P254); break; #elif FP_PRIME == 256 case BN_P256: ASSIGN(BN_P256); break; #elif FP_PRIME == 638 case BN_P638: ASSIGN(BN_P638); break; case B12_P638: ASSIGN(B12_P638); break; #endif default: (void)str; THROW(ERR_NO_VALID); break; } fp2_zero(g->z); fp_set_dig(g->z[0], 1); g->norm = 1; ep2_copy(&(ctx->ep2_g), g); fp_copy(ctx->ep2_a[0], a[0]); fp_copy(ctx->ep2_a[1], a[1]); fp_copy(ctx->ep2_b[0], b[0]); fp_copy(ctx->ep2_b[1], b[1]); bn_copy(&(ctx->ep2_r), r); /* I don't have a better place for this. */ fp_prime_calc(); #if defined(EP_PRECO) ep2_mul_pre((ep2_t *)ep2_curve_get_tab(), &(ctx->ep2_g)); #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep2_free(g); fp2_free(a); fp2_free(b); bn_free(r); } }