Example #1
0
static void test_gf33m_inverse(void) {
    element_random(a3);
    element_invert(b3, a3);
    element_mul(a3, a3, b3);
    element_ptr a0 = element_item(a3, 0);
    EXPECT(!element_cmp(a0, e1));
}
Example #2
0
static val_ptr run_item(val_ptr v[]) {
	mpz_t z;
	mpz_init(z);
	element_to_mpz(z, v[1]->elem);
	int i = mpz_get_si(z);
	mpz_clear(z);
	element_ptr a = element_item(v[0]->elem, i);
	element_ptr e = (element_ptr)pbc_malloc(sizeof(*e));
	element_init_same_as(e, a);
	element_set(e, a);
	return val_new_element(e);
}
Example #3
0
File: d_param.c Project: blynn/pbc
// Define l = aX + bY + c where a, b, c are in Fq.
// Compute e0 = l(Q) specialized for the case when Q has the form
// (Qx, Qy * sqrt(v)) where Qx, Qy are in Fqd and v is the quadratic nonresidue
// used to construct the quadratic field extension Fqk of Fqd.
static inline void d_miller_evalfn(element_t e0,
    element_t a, element_t b, element_t c, element_t Qx, element_t Qy) {
  element_ptr re_out = element_x(e0);
  element_ptr im_out = element_y(e0);

  int i;
  int d = polymod_field_degree(re_out->field);
  for (i = 0; i < d; i++) {
    element_mul(element_item(re_out, i), element_item(Qx, i), a);
    element_mul(element_item(im_out, i), element_item(Qy, i), b);
  }
  element_add(element_item(re_out, 0), element_item(re_out, 0), c);
}
Example #4
0
File: d_param.c Project: blynn/pbc
void pbc_param_init_d_gen(pbc_param_ptr p, pbc_cm_ptr cm) {
  d_param_init(p);
  d_param_ptr param = p->data;
  field_t Fq, Fqx, Fqd;
  element_t irred, nqr;
  int d = cm->k / 2;
  int i;

  compute_cm_curve(param, cm);

  field_init_fp(Fq, param->q);
  field_init_poly(Fqx, Fq);
  element_init(irred, Fqx);
  do {
    poly_random_monic(irred, d);
  } while (!poly_is_irred(irred));
  field_init_polymod(Fqd, irred);

  // Find a quadratic nonresidue of Fqd lying in Fq.
  element_init(nqr, Fqd);
  do {
    element_random(((element_t *) nqr->data)[0]);
  } while (element_is_sqr(nqr));

  param->coeff = pbc_realloc(param->coeff, sizeof(mpz_t) * d);

  for (i=0; i<d; i++) {
    mpz_init(param->coeff[i]);
    element_to_mpz(param->coeff[i], element_item(irred, i));
  }
  element_to_mpz(param->nqr, ((element_t *) nqr->data)[0]);

  element_clear(nqr);
  element_clear(irred);

  field_clear(Fqx);
  field_clear(Fqd);
  field_clear(Fq);
}
Example #5
0
static element_ptr mulg_item(element_ptr e, int i) {
  return element_item(e->data, i);
}
Example #6
0
File: f_param.c Project: blynn/pbc
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);
}
Example #7
0
File: f_param.c Project: blynn/pbc
static void f_init_pairing(pairing_t pairing, void *data) {
  f_param_ptr param = data;
  f_pairing_data_ptr p;
  element_t irred;
  element_t e0, e1, e2;
  p = pairing->data = pbc_malloc(sizeof(f_pairing_data_t));
  mpz_init(pairing->r);
  mpz_set(pairing->r, param->r);
  field_init_fp(pairing->Zr, pairing->r);
  field_init_fp(p->Fq, param->q);
  p->Fq->nqr = pbc_malloc(sizeof(element_t));
  element_init(p->Fq->nqr, p->Fq);
  element_set_mpz(p->Fq->nqr, param->beta);
  field_init_quadratic(p->Fq2, p->Fq);
  field_init_poly(p->Fq2x, p->Fq2);
  element_init(irred, p->Fq2x);
  // Call poly_set_coeff1() first so we can use element_item() for the other
  // coefficients.
  poly_set_coeff1(irred, 6);

  element_init(p->negalpha, p->Fq2);
  element_init(p->negalphainv, p->Fq2);
  element_set_mpz(element_x(p->negalpha), param->alpha0);
  element_set_mpz(element_y(p->negalpha), param->alpha1);

  element_set(element_item(irred, 0), p->negalpha);
  field_init_polymod(p->Fq12, irred);
  element_neg(p->negalpha, p->negalpha);
  element_invert(p->negalphainv, p->negalpha);
  element_clear(irred);

  element_init(e0, p->Fq);
  element_init(e1, p->Fq);
  element_init(e2, p->Fq2);

  // Initialize the curve Y^2 = X^3 + b.
  element_set_mpz(e1, param->b);
  field_init_curve_ab(p->Eq, e0, e1, pairing->r, NULL);

  // Initialize the curve Y^2 = X^3 - alpha0 b - alpha1 sqrt(beta) b.
  element_set_mpz(e0, param->alpha0);
  element_neg(e0, e0);
  element_mul(element_x(e2), e0, e1);
  element_set_mpz(e0, param->alpha1);
  element_neg(e0, e0);
  element_mul(element_y(e2), e0, e1);
  element_clear(e0);
  element_init(e0, p->Fq2);
  field_init_curve_ab(p->Etwist, e0, e2, pairing->r, NULL);
  element_clear(e0);
  element_clear(e1);
  element_clear(e2);

  mpz_t ndonr;
  mpz_init(ndonr);
  // ndonr temporarily holds the trace.
  mpz_sub(ndonr, param->q, param->r);
  mpz_add_ui(ndonr, ndonr, 1);
  // TODO: We can use a smaller quotient_cmp, but I have to figure out
  // BN curves again.
  pbc_mpz_curve_order_extn(ndonr, param->q, ndonr, 12);
  mpz_divexact(ndonr, ndonr, param->r);
  mpz_divexact(ndonr, ndonr, param->r);
  field_curve_set_quotient_cmp(p->Etwist, ndonr);
  mpz_clear(ndonr);

  pairing->G1 = p->Eq;
  pairing->G2 = p->Etwist;
  pairing_GT_init(pairing, p->Fq12);
  pairing->finalpow = f_finalpow;
  pairing->map = f_pairing;
  pairing->clear_func = f_pairing_clear;

  mpz_init(p->tateexp);
  /* unoptimized tate exponent
  mpz_pow_ui(p->tateexp, param->q, 12);
  mpz_sub_ui(p->tateexp, p->tateexp, 1);
  mpz_divexact(p->tateexp, p->tateexp, param->r);
  */
  mpz_ptr z = p->tateexp;
  mpz_mul(z, param->q, param->q);
  mpz_sub_ui(z, z, 1);
  mpz_mul(z, z, param->q);
  mpz_mul(z, z, param->q);
  mpz_add_ui(z, z, 1);
  mpz_divexact(z, z, param->r);

  element_init(p->xpowq2, p->Fq2);
  element_init(p->xpowq6, p->Fq2);
  element_init(p->xpowq8, p->Fq2);
  element_t xpowq;
  element_init(xpowq, p->Fq12);

  //there are smarter ways since we know q = 1 mod 6
  //and that x^6 = -alpha
  //but this is fast enough
  element_set1(element_item(xpowq, 1));
  element_pow_mpz(xpowq, xpowq, param->q);
  element_pow_mpz(xpowq, xpowq, param->q);
  element_set(p->xpowq2, element_item(xpowq, 1));

  element_pow_mpz(xpowq, xpowq, param->q);
  element_pow_mpz(xpowq, xpowq, param->q);
  element_pow_mpz(xpowq, xpowq, param->q);
  element_pow_mpz(xpowq, xpowq, param->q);
  element_set(p->xpowq6, element_item(xpowq, 1));

  element_pow_mpz(xpowq, xpowq, param->q);
  element_pow_mpz(xpowq, xpowq, param->q);
  element_set(p->xpowq8, element_item(xpowq, 1));

  element_clear(xpowq);
}
Example #8
0
/* computation of $c <- U ^ {3^{3m} - 1}$
 * This is the algorithm 6 in the paper above. */
static void algorithm6(element_t c, element_t u) {
    element_ptr u0 = ITEM(u,0,0), u1 = ITEM(u,0,1), u2 = ITEM(u,1,0), u3 =
                                           ITEM(u,1,1), u4 = ITEM(u,2,0), u5 = ITEM(u,2,1);
    field_ptr f = FIELD(u0); /*GF(3^m)*/
    field_t f3; /*GF(3^{3*m})*/
    field_init_gf33m(f3, f);
    element_t v0, v1, m0, m1, m2, a0, a1, i;
    element_init(v0, f3);
    element_init(v1, f3);
    element_init(m0, f3);
    element_init(m1, f3);
    element_init(m2, f3);
    element_init(a0, f3);
    element_init(a1, f3);
    element_init(i, f3);
    element_set(element_item(v0, 0), u0);
    element_set(element_item(v0, 1), u2);
    element_set(element_item(v0, 2), u4);
    element_set(element_item(v1, 0), u1);
    element_set(element_item(v1, 1), u3);
    element_set(element_item(v1, 2), u5);
    element_mul(m0, v0, v0);
    element_mul(m1, v1, v1);
    element_mul(m2, v0, v1);
    element_sub(a0, m0, m1);
    element_add(a1, m0, m1);
    element_invert(i, a1);
    element_mul(v0, a0, i);
    element_mul(v1, m2, i);
    element_set(ITEM(c,0,0), element_item(v0, 0));
    element_set(ITEM(c,1,0), element_item(v0, 1));
    element_set(ITEM(c,2,0), element_item(v0, 2));
    element_set(ITEM(c,0,1), element_item(v1, 0));
    element_set(ITEM(c,1,1), element_item(v1, 1));
    element_set(ITEM(c,2,1), element_item(v1, 2));
    element_clear(v0);
    element_clear(v1);
    element_clear(m0);
    element_clear(m1);
    element_clear(m2);
    element_clear(a0);
    element_clear(a1);
    element_clear(i);
    field_clear(f3);
}
Example #9
0
File: d_param.c Project: blynn/pbc
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);
}
Example #10
0
File: d_param.c Project: blynn/pbc
// 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);
}
Example #11
0
void KSET0(element_t out){
    element_set0(out);
    element_ptr re_out = element_x(out);
    element_set0(element_item(re_out,0));
}