Beispiel #1
0
// Existing points are invalidated as this mangles c.
void field_reinit_curve_twist(field_ptr c) {
	curve_data_ptr cdp = (curve_data_ptr)c->data;
  element_ptr nqr = field_get_nqr(cdp->field);
  element_mul(cdp->a, cdp->a, nqr);
  element_mul(cdp->a, cdp->a, nqr);
  element_mul(cdp->b, cdp->b, nqr);
  element_mul(cdp->b, cdp->b, nqr);
  element_mul(cdp->b, cdp->b, nqr);

  // Recompute generators.
  curve_random_no_cofac_solvefory(cdp->gen_no_cofac);
  if (cdp->cofac) {
    element_mul_mpz(cdp->gen, cdp->gen_no_cofac, cdp->cofac);
  } else{
    element_set(cdp->gen, cdp->gen_no_cofac);
  }
}
Beispiel #2
0
// Return the quadratic nonresidue used to build this field.
// Should only be called from routines used exclusively by the generic quadratic
// extension code.
static inline element_ptr fq_nqr(field_ptr f) {
  return field_get_nqr((field_ptr) f->data);
}
Beispiel #3
0
void pbc_param_init_f_gen(pbc_param_t p, int bits) {
  f_init(p);
  f_param_ptr fp = p->data;
  //36 is a 6-bit number
  int xbit = (bits - 6) / 4;
  //TODO: use binary search to find smallest appropriate x
  mpz_t x, t;
  mpz_ptr q = fp->q;
  mpz_ptr r = fp->r;
  mpz_ptr b = fp->b;
  field_t Fq, Fq2, Fq2x;
  element_t e1;
  element_t f;
  field_t c;
  element_t P;

  mpz_init(x);
  mpz_init(t);
  mpz_setbit(x, xbit);
  for (;;) {
    mpz_mul(t, x, x);
    mpz_mul_ui(t, t, 6);
    mpz_add_ui(t, t, 1);
    tryminusx(q, x);
    mpz_sub(r, q, t);
    mpz_add_ui(r, r, 1);
    if (mpz_probab_prime_p(q, 10) && mpz_probab_prime_p(r, 10)) break;

    tryplusx(q, x);
    mpz_sub(r, q, t);
    mpz_add_ui(r, r, 1);
    if (mpz_probab_prime_p(q, 10) && mpz_probab_prime_p(r, 10)) break;

    mpz_add_ui(x, x, 1);
  }

  field_init_fp(Fq, q);
  element_init(e1, Fq);

  for (;;) {
    element_random(e1);
    field_init_curve_b(c, e1, r, NULL);
    element_init(P, c);

    element_random(P);

    element_mul_mpz(P, P, r);
    if (element_is0(P)) break;
    element_clear(P);
    field_clear(c);
  }
  element_to_mpz(b, e1);
  element_clear(e1);
  field_init_quadratic(Fq2, Fq);
  element_to_mpz(fp->beta, field_get_nqr(Fq));
  field_init_poly(Fq2x, Fq2);
  element_init(f, Fq2x);

  // Find an irreducible polynomial of the form f = x^6 + alpha.
  // Call poly_set_coeff1() first so we can use element_item() for the other
  // coefficients.
  poly_set_coeff1(f, 6);
  for (;;) {
    element_random(element_item(f, 0));
    if (poly_is_irred(f)) break;
  }

  //extend F_q^2 using f = x^6 + alpha
  //see if sextic twist contains a subgroup of order r
  //if not, it's the wrong twist: replace alpha with alpha^5
  {
    field_t ctest;
    element_t Ptest;
    mpz_t z0, z1;
    mpz_init(z0);
    mpz_init(z1);
    element_init(e1, Fq2);
    element_set_mpz(e1, fp->b);
    element_mul(e1, e1, element_item(f, 0));
    element_neg(e1, e1);

    field_init_curve_b(ctest, e1, r, NULL);
    element_init(Ptest, ctest);
    element_random(Ptest);

    //I'm not sure what the #E'(F_q^2) is, but
    //it definitely divides n_12 = #E(F_q^12). It contains a
    //subgroup of order r if and only if
    //(n_12 / r^2)P != O for some (in fact most) P in E'(F_q^6)
    mpz_pow_ui(z0, q, 12);
    mpz_add_ui(z0, z0, 1);
    pbc_mpz_trace_n(z1, q, t, 12);
    mpz_sub(z1, z0, z1);
    mpz_mul(z0, r, r);
    mpz_divexact(z1, z1, z0);

    element_mul_mpz(Ptest, Ptest, z1);
    if (element_is0(Ptest)) {
      mpz_set_ui(z0, 5);
      element_pow_mpz(element_item(f, 0), element_item(f, 0), z0);
    }
    element_clear(e1);
    element_clear(Ptest);
    field_clear(ctest);
    mpz_clear(z0);
    mpz_clear(z1);
  }

  element_to_mpz(fp->alpha0, element_x(element_item(f, 0)));
  element_to_mpz(fp->alpha1, element_y(element_item(f, 0)));

  element_clear(f);

  field_clear(Fq2x);
  field_clear(Fq2);
  field_clear(Fq);

  mpz_clear(t);
  mpz_clear(x);
}
Beispiel #4
0
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);
}