static void d_init_pairing(pairing_ptr pairing, void *data) { d_param_ptr param = data; pptr p; element_t a, b; element_t irred; int d = param->k / 2; int i; if (param->k % 2) pbc_die("k must be even"); mpz_init(pairing->r); mpz_set(pairing->r, param->r); field_init_fp(pairing->Zr, pairing->r); pairing->map = cc_pairing; pairing->prod_pairings = cc_pairings_affine; pairing->is_almost_coddh = cc_is_almost_coddh; p = pairing->data = pbc_malloc(sizeof(*p)); field_init_fp(p->Fq, param->q); element_init(a, p->Fq); element_init(b, p->Fq); element_set_mpz(a, param->a); element_set_mpz(b, param->b); field_init_curve_ab(p->Eq, a, b, pairing->r, param->h); field_init_poly(p->Fqx, p->Fq); element_init(irred, p->Fqx); poly_set_coeff1(irred, d); for (i = 0; i < d; i++) { element_set_mpz(element_item(irred, i), param->coeff[i]); } field_init_polymod(p->Fqd, irred); element_clear(irred); p->Fqd->nqr = pbc_malloc(sizeof(element_t)); element_init(p->Fqd->nqr, p->Fqd); element_set_mpz(((element_t *) p->Fqd->nqr->data)[0], param->nqr); field_init_quadratic(p->Fqk, p->Fqd); // Compute constants involved in the final powering. if (param->k == 6) { mpz_ptr q = param->q; mpz_ptr z = pairing->phikonr; mpz_init(z); mpz_mul(z, q, q); mpz_sub(z, z, q); mpz_add_ui(z, z, 1); mpz_divexact(z, z, pairing->r); element_ptr e = p->xpowq; element_init(e, p->Fqd); element_set1(((element_t *) e->data)[1]); element_pow_mpz(e, e, q); element_init(p->xpowq2, p->Fqd); element_square(p->xpowq2, e); } else { mpz_init(p->tateexp); mpz_sub_ui(p->tateexp, p->Fqk->order, 1); mpz_divexact(p->tateexp, p->tateexp, pairing->r); } field_init_curve_ab_map(p->Etwist, p->Eq, element_field_to_polymod, p->Fqd, pairing->r, NULL); field_reinit_curve_twist(p->Etwist); mpz_t ndonr; mpz_init(ndonr); // ndonr temporarily holds the trace. mpz_sub(ndonr, param->q, param->n); mpz_add_ui(ndonr, ndonr, 1); // Negate it because we want the trace of the twist. mpz_neg(ndonr, ndonr); pbc_mpz_curve_order_extn(ndonr, param->q, ndonr, d); mpz_divexact(ndonr, ndonr, param->r); field_curve_set_quotient_cmp(p->Etwist, ndonr); mpz_clear(ndonr); element_init(p->nqrinv, p->Fqd); element_invert(p->nqrinv, field_get_nqr(p->Fqd)); element_init(p->nqrinv2, p->Fqd); element_square(p->nqrinv2, p->nqrinv); pairing->G1 = p->Eq; pairing->G2 = p->Etwist; p->k = param->k; pairing_GT_init(pairing, p->Fqk); pairing->finalpow = cc_finalpow; // By default use affine coordinates. cc_miller_no_denom_fn = cc_miller_no_denom_affine; pairing->option_set = d_pairing_option_set; pairing->pp_init = d_pairing_pp_init; pairing->pp_clear = d_pairing_pp_clear; pairing->pp_apply = d_pairing_pp_apply; pairing->clear_func = d_pairing_clear; element_clear(a); element_clear(b); }
void pbc_param_init_e_gen(pbc_param_t par, int rbits, int qbits) { e_init(par); e_param_ptr p = par->data; //3 takes 2 bits to represent int hbits = (qbits - 2) / 2 - rbits; mpz_ptr q = p->q; mpz_ptr r = p->r; mpz_ptr h = p->h; mpz_t n; field_t Fq; field_t cc; element_t j; int found = 0; //won't find any curves is hbits is too low if (hbits < 3) hbits = 3; mpz_init(n); do { int i; mpz_set_ui(r, 0); if (rand() % 2) { p->exp2 = rbits - 1; p->sign1 = 1; } else { p->exp2 = rbits; p->sign1 = -1; } mpz_setbit(r, p->exp2); p->exp1 = (rand() % (p->exp2 - 1)) + 1; //use q as a temp variable mpz_set_ui(q, 0); mpz_setbit(q, p->exp1); if (p->sign1 > 0) { mpz_add(r, r, q); } else { mpz_sub(r, r, q); } if (rand() % 2) { p->sign0 = 1; mpz_add_ui(r, r, 1); } else { p->sign0 = -1; mpz_sub_ui(r, r, 1); } if (!mpz_probab_prime_p(r, 10)) continue; for (i=0; i<10; i++) { //use q as a temp variable mpz_set_ui(q, 0); mpz_setbit(q, hbits + 1); pbc_mpz_random(h, q); mpz_mul(h, h, h); mpz_mul_ui(h, h, 3); //finally q takes the value it should mpz_mul(n, r, r); mpz_mul(n, n, h); mpz_add_ui(q, n, 1); if (mpz_probab_prime_p(q, 10)) { found = 1; break; } } } while (!found); /* do { mpz_set_ui(r, 0); mpz_setbit(r, rbits); pbc_mpz_random(r, r); mpz_nextprime(r, r); mpz_mul(n, r, r); mpz_mul_ui(n, n, 3); mpz_add_ui(q, n, 1); } while (!mpz_probab_prime_p(q, 10)); */ field_init_fp(Fq, q); element_init(j, Fq); element_set_si(j, 1); field_init_curve_b(cc, j, n, NULL); element_clear(j); // We may need to twist it. { // Pick a random point P and twist the curve if P has the wrong order. element_t P; element_init(P, cc); element_random(P); element_mul_mpz(P, P, n); if (!element_is0(P)) field_reinit_curve_twist(cc); element_clear(P); } element_to_mpz(p->a, curve_field_a_coeff(cc)); element_to_mpz(p->b, curve_field_b_coeff(cc)); mpz_clear(n); }
// Computes a curve and sets fp to the field it is defined over using the // complex multiplication method, where cm holds the appropriate information // (e.g. discriminant, field order). static void compute_cm_curve(d_param_ptr param, pbc_cm_ptr cm) { element_t hp, root; field_t fp, fpx; field_t cc; field_init_fp(fp, cm->q); field_init_poly(fpx, fp); element_init(hp, fpx); mpz_t *coefflist; int n = (int)pbc_hilbert(&coefflist, cm->D); // Temporarily set the coefficient of x^{n-1} to 1 so hp has degree n - 1, // allowing us to use poly_coeff(). poly_set_coeff1(hp, n - 1); int i; for (i = 0; i < n; i++) { element_set_mpz(element_item(hp, i), coefflist[i]); } pbc_hilbert_free(coefflist, n); // TODO: Remove x = 0, 1728 roots. // TODO: What if there are no roots? //printf("hp "); //element_out_str(stdout, 0, hp); //printf("\n"); element_init(root, fp); poly_findroot(root, hp); //printf("root = "); //element_out_str(stdout, 0, root); //printf("\n"); element_clear(hp); field_clear(fpx); // The root is the j-invariant of the desired curve. field_init_curve_j(cc, root, cm->n, NULL); element_clear(root); // We may need to twist it. { // Pick a random point P and twist the curve if it has the wrong order. element_t P; element_init(P, cc); element_random(P); element_mul_mpz(P, P, cm->n); if (!element_is0(P)) field_reinit_curve_twist(cc); element_clear(P); } mpz_set(param->q, cm->q); mpz_set(param->n, cm->n); mpz_set(param->h, cm->h); mpz_set(param->r, cm->r); element_to_mpz(param->a, curve_field_a_coeff(cc)); element_to_mpz(param->b, curve_field_b_coeff(cc)); param->k = cm->k; { mpz_t z; mpz_init(z); // Compute order of curve in F_q^k. // n = q - t + 1 hence t = q - n + 1 mpz_sub(z, param->q, param->n); mpz_add_ui(z, z, 1); pbc_mpz_trace_n(z, param->q, z, param->k); mpz_pow_ui(param->nk, param->q, param->k); mpz_sub_ui(z, z, 1); mpz_sub(param->nk, param->nk, z); mpz_mul(z, param->r, param->r); mpz_divexact(param->hk, param->nk, z); mpz_clear(z); } field_clear(cc); field_clear(fp); }