예제 #1
0
파일: sing.c 프로젝트: blynn/pbc
int main(void)
{
    field_t c;
    field_t Z19;
    element_t P, Q, R;
    mpz_t q, z;
    element_t a;
    int i;

    mpz_init(q);
    mpz_init(z);

    mpz_set_ui(q, 19);

    field_init_fp(Z19, q);
    element_init(a, Z19);

    field_init_curve_singular_with_node(c, Z19);

    element_init(P, c);
    element_init(Q, c);
    element_init(R, c);

    //(3,+/-6) is a generator
    //we have an isomorphism from E_ns to F_19^*
    // (3,6) --> 3
    //(generally (x,y) --> (y+x)/(y-x)

    curve_set_si(R, 3, 6);

    for (i=1; i<=18; i++) {
        mpz_set_si(z, i);
        element_mul_mpz(Q, R, z);
        element_printf("%dR = %B\n", i, Q);
    }

    mpz_set_ui(z, 6);
    element_mul_mpz(P, R, z);
    //P has order 3
    element_printf("P = %B\n", P);

    for (i=1; i<=3; i++) {
        mpz_set_si(z, i);
        element_mul_mpz(Q, R, z);
        tate_3(a, P, Q, R);
        element_printf("e_3(P,%dP) = %B\n", i, a);
    }

    element_double(P, R);
    //P has order 9
    element_printf("P = %B\n", P);
    for (i=1; i<=9; i++) {
        mpz_set_si(z, i);
        element_mul_mpz(Q, P, z);
        tate_9(a, P, Q, R);
        element_printf("e_9(P,%dP) = %B\n", i, a);
    }

    return 0;
}
예제 #2
0
파일: pbc.cpp 프로젝트: mahnushm/MpcLib
static val_ptr run_zmod(val_ptr v[]) {
	element_ptr e = v[0]->elem;
	mpz_t z;
	mpz_init(z);
	element_to_mpz(z, e);
	field_ptr f = (field_ptr)pbc_malloc(sizeof(*f));
	field_init_fp(f, z);
	mpz_clear(z);
	return val_new_field(f);
}
예제 #3
0
파일: singular.c 프로젝트: jun-kim/SEDA
void pairing_init_singular_with_node(pairing_t pairing, mpz_t q) {
  sn_pairing_data_ptr p;

  mpz_init(pairing->r);
  mpz_sub_ui(pairing->r, q, 1);
  field_init_fp(pairing->Zr, pairing->r);
  pairing->map = sn_pairing;

  p = pairing->data = pbc_malloc(sizeof(sn_pairing_data_t));
  field_init_fp(p->Fq, q);
  field_init_curve_singular_with_node(p->Eq, p->Fq);

  //mpz_init(p->tateexp);
  //mpz_sub_ui(p->tateexp, p->Fq->order, 1);
  //mpz_divexact(p->tateexp, p->tateexp, pairing->r);

  pairing->G2 = pairing->G1 = p->Eq;

  pairing_GT_init(pairing, p->Fq);
}
예제 #4
0
static void e_init_pairing(pairing_t pairing, void *data) {
  e_param_ptr param = data;
  e_pairing_data_ptr p;
  element_t a, b;

  mpz_init(pairing->r);
  mpz_set(pairing->r, param->r);
  field_init_fp(pairing->Zr, pairing->r);
  pairing->map = e_pairing;
  e_miller_fn = e_miller_proj;

  p = pairing->data = pbc_malloc(sizeof(e_pairing_data_t));
  p->exp2 = param->exp2;
  p->exp1 = param->exp1;
  p->sign1 = param->sign1;
  p->sign0 = param->sign0;
  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);

  //k=1, hence phikonr = (p-1)/r
  mpz_init(pairing->phikonr);
  mpz_sub_ui(pairing->phikonr, p->Fq->order, 1);
  mpz_divexact(pairing->phikonr, pairing->phikonr, pairing->r);

  pairing->G2 = pairing->G1 = p->Eq;
  pairing_GT_init(pairing, p->Fq);
  pairing->finalpow = e_finalpow;
  pairing->phi = phi_identity;
  pairing->option_set = e_pairing_option_set;
  pairing->clear_func = e_pairing_clear;

  element_init(p->R, p->Eq);
  curve_set_gen_no_cofac(p->R);

  element_clear(a);
  element_clear(b);
}
예제 #5
0
파일: d_param.c 프로젝트: 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);
}
예제 #6
0
파일: eta_T_3.c 프로젝트: JasonSome/pbc
static void eta_T_3_init_pairing(pairing_t pairing, params *p) {
    mpz_init(pairing->r);
    mpz_set(pairing->r, p->n);
    field_init_fp(pairing->Zr, pairing->r);

    pairing_data_ptr dp = pbc_malloc(sizeof(*dp));
    mpz_init(dp->n2);
    mpz_set(dp->n2, p->n2);
    field_init_gf3m(dp->gf3m, p->m, p->t);
    field_init_gf32m(dp->gf32m, dp->gf3m);
    field_init_gf33m(dp->gf36m, dp->gf32m);
    pairing_GT_init(pairing, dp->gf36m);
    pairing->GT->name = "eta_T_3 group of roots of 1";
    pairing->GT->random = GT_random;
    pairing->G2 = pairing->G1 = pbc_malloc(sizeof(field_t));
    field_init_eta_T_3(pairing->G1, dp->gf3m);
    pairing->G1->pairing = pairing;
    mpz_set(pairing->G1->order, p->n);
    mpz_set(pairing->GT->order, p->n);
    pairing->map = eta_T_pairing;
    pairing->data = dp;
    pairing->clear_func = eta_T_3_pairing_clear;
}
예제 #7
0
파일: 19.c 프로젝트: blynn/pbc
int main(void) {
  field_t c;
  field_t Z19;
  element_t P, Q, R;
  mpz_t q, z;
  element_t a, b;
  int i;

  field_t Z19_2;
  field_t c2;
  element_t P2, Q2, R2;
  element_t a2;

  mpz_init(q);
  mpz_init(z);

  mpz_set_ui(q, 19);

  field_init_fp(Z19, q);
  element_init(a, Z19);
  element_init(b, Z19);

  element_set_si(a, 1);
  element_set_si(b, 6);

  mpz_set_ui(q, 18);
  field_init_curve_ab(c, a, b, q, NULL);
  element_init(P, c);
  element_init(Q, c);
  element_init(R, c);

  printf("Y^2 = X^3 + X + 6 over F_19\n");
  //(0,+/-5) is a generator
  element_set0(a);
  curve_from_x(R, a);

  for (i=1; i<19; i++) {
    mpz_set_si(z, i);
    element_mul_mpz(Q, R, z);
    element_printf("%dR = %B\n", i, Q);
  }

  mpz_set_ui(z, 6);
  element_mul_mpz(P, R, z);
  //P has order 3
  element_printf("P = %B\n", P);

  for (i=1; i<=3; i++) {
    mpz_set_si(z, i);
    element_mul_mpz(Q, R, z);
    tate_3(a, P, Q, R);
    element_printf("e_3(P,%dR) = %B\n", i, a);
  }

  element_double(P, R);
  //P has order 9
  element_printf("P = %B\n", P);
  for (i=1; i<=9; i++) {
    mpz_set_si(z, i);
    //we're supposed to use multiples of R
    //but 2R works just as well and it allows us
    //to use R as the offset every time
    element_mul_mpz(Q, P, z);
    tate_9(a, P, Q, R);
    element_printf("e_9(P,%dP) = %B\n", i, a);
  }

  //to do the pairing on all of E(F_19) we need to move to F_19^2
  //or compute the rational function explicitly
  printf("moving to F_19^2\n");
  field_init_fi(Z19_2, Z19);

  //don't need to tell it the real order
  field_init_curve_ab_map(c2, c, element_field_to_fi, Z19_2, q, NULL);
  element_init(P2, c2);
  element_init(Q2, c2);
  element_init(R2, c2);

  element_init(a2, Z19_2);
  element_set0(a2);
  curve_from_x(P2, a2);

  element_random(R2);

  element_printf("P = %B\n", P2);

  for (i=1; i<=18; i++) {
    mpz_set_si(z, i);
    element_mul_mpz(Q2, P2, z);
    tate_18(a2, P2, Q2, R2, P2);
    element_printf("e_18(P,%dP) = %B\n", i, a2);
  }

  element_clear(P2);
  element_clear(Q2);
  element_clear(R2);
  element_clear(a2);
  field_clear(c2);
  field_clear(Z19_2);

  field_clear(c);
  element_clear(a);
  element_clear(b);
  element_clear(P);
  element_clear(Q);
  element_clear(R);
  field_clear(Z19);

  mpz_clear(q);
  mpz_clear(z);
  return 0;
}
예제 #8
0
int main(void) {
  mpz_t p, q, N, d;
  mpz_t dmp1, dmq1;
  mpz_t ipmq, iqmp;
  mpz_t adq, adp;

  field_t f;
  element_t a, b;
  double t0, t1, tnaive = 0, tcrt=0;
  int i, n;

  mpz_init(p);
  mpz_init(q);
  mpz_init(N);
  mpz_init(d);
  mpz_init(dmp1);
  mpz_init(dmq1);
  mpz_init(ipmq);
  mpz_init(iqmp);
  mpz_init(adp);
  mpz_init(adq);
  pbc_mpz_randomb(p, 512);
  pbc_mpz_randomb(q, 512);
  mpz_nextprime(p, p);
  mpz_nextprime(q, q);
  mpz_mul(N, p, q);
  mpz_invert(ipmq, p, q);
  mpz_invert(iqmp, q, p);

  field_init_fp(f, N);
  element_init(a, f);
  element_init(b, f);
  n = 10;
  for (i=0; i<n; i++) {
    pbc_mpz_random(d, N);
    element_random(a);
    t0 = pbc_get_time();
    element_pow_mpz(b, a, d);
    t1 = pbc_get_time();
    tnaive += t1 - t0;

    mpz_sub_ui(p, p, 1);
    mpz_sub_ui(q, q, 1);

    mpz_mod(dmp1, d, p);
    mpz_mod(dmq1, d, q);

    mpz_add_ui(p, p, 1);
    mpz_add_ui(q, q, 1);

    element_to_mpz(adq, a);
    element_to_mpz(adp, a);

    t0 = pbc_get_time();
    mpz_powm(adp, adp, d, p);
    mpz_powm(adq, adq, d, q);

    /* textbook CRT
    mpz_mul(adp, adp, q);
    mpz_mul(adp, adp, iqmp);
    mpz_mul(adq, adq, p);
    mpz_mul(adq, adq, ipmq);
    mpz_add(adp, adp, adq);
    */
    // Garner's algorithm
    mpz_sub(adq, adq, adp);
    mpz_mul(adq, adq, ipmq);
    mpz_mod(adq, adq, q);
    mpz_mul(adq, adq, p);
    mpz_add(adp, adp, adq);

    t1 = pbc_get_time();
    tcrt += t1 - t0;
    element_set_mpz(b, adp);
  }
  printf("average RSA exp time = %lf\n", tnaive / n);
  printf("average RSA exp time (CRT) = %lf\n", tcrt / n);
  return 0;
}
예제 #9
0
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);
}
예제 #10
0
파일: 59.c 프로젝트: Russ36363/pbc-thesis
int main(void)
{
    int i;
    element_t g, h;
    element_t w0, w1;
    element_t a, b;
    mpz_t prime, cofac;

    mpz_init(prime);
    mpz_init(order);
    mpz_init(cofac);
    mpz_set_ui(prime, 59);

    field_init_fp(Fq, prime);

    element_init(a, Fq);
    element_init(b, Fq);

    field_init_fi(Fq2, Fq);

    element_set1(a);
    element_set0(b);
    mpz_set_ui(order, 5);
    mpz_set_ui(cofac, 12);

    field_init_curve_ab(E, a, b, order, cofac);

    element_clear(a);
    element_clear(b);
    element_init(a, Fq2);
    element_init(b, Fq2);
    element_set1(a);
    element_set0(b);

    mpz_mul(cofac, cofac, cofac);
    field_init_curve_ab(E2, a, b, order, NULL);

    element_init(g, E2);
    element_init(h, E2);

    element_init(w0, Fq2);
    element_init(w1, Fq2);

    /*
    do {
	element_random(g);
    } while (element_is1(g));
    for (i=1; i<5; i++) {
	element_mul(h, h, g);
	element_printf("%d: %B\n", i, h);
	element_printf("tangent = ");
	do_tangent(h);
    }
    */
    element_set_str(g, "[[25,0],[30,0]", 0);
    element_set_str(h, "[[34,0],[0,30]", 0);
    weil(w0, g, h);
    element_printf("weil: %B\n", w0);

    element_set1(w1);
    for (i=1; i<6; i++) {
	element_mul(w1, w1, w0);
	element_printf("%d: %B\n", i, w1);
    }

    fasterweil(w0, g, h);
    element_printf("fasterweil: %B\n", w0);

    element_set1(w1);
    for (i=1; i<6; i++) {
	element_mul(w1, w1, w0);
	element_printf("%d: %B\n", i, w1);
    }

    fasterweil2(w0, g, h);
    element_printf("fasterweil2: %B\n", w0);

    tate(w0, g, h);
    element_printf("tate: %B\n", w0);

    element_set1(w1);
    for (i=1; i<6; i++) {
	element_mul(w1, w1, w0);
	element_printf("%d: %B\n", i, w1);
    }

    shipseystange(w0, g, h);
    element_printf("ss-tate: %B\n", w0);

    element_set1(w1);
    for (i=1; i<6; i++) {
	element_mul(w1, w1, w0);
	element_printf("%d: %B\n", i, w1);
    }
    return 0;
}
예제 #11
0
int main(void) {
  field_t fp, fx;
  mpz_t prime;
  darray_t list;
  int p = 7;

  // Exercise poly_is_irred() with a sieve of Erastosthenes for polynomials.
  darray_init(list);
  mpz_init(prime);
  mpz_set_ui(prime, p);
  field_init_fp(fp, prime);
  field_init_poly(fx, fp);
  element_t e;
  element_init(e, fp);
  // Enumerate polynomials in F_p[x] up to degree 2.
  int a[3], d;
  a[0] = a[1] = a[2] = 0;
  for(;;) {
    element_ptr f = pbc_malloc(sizeof(*f));
    element_init(f, fx);
    int j;
    for(j = 0; j < 3; j++) {
      element_set_si(e, a[j]);
      poly_set_coeff(f, e, j);
    }

    // Test poly_degree().
    for(j = 2; !a[j] && j >= 0; j--);
    EXPECT(poly_degree(f) == j);

    // Add monic polynomials to the list.
    if (j >= 0 && a[j] == 1) darray_append(list, f);
    else {
      element_clear(f);
      free(f);
    }

    // Next!
    d = 0;
    for(;;) {
      a[d]++;
      if (a[d] >= p) {
        a[d] = 0;
        d++;
        if (d > 2) goto break2;
      } else break;
    }
  }
break2: ;

  // Find all composite monic polynomials of degree 3 or less.
  darray_t prodlist;
  darray_init(prodlist);

  void outer(void *data) {
    element_ptr f = data;
    void inner(void *data2) {
      element_ptr g = data2;
      if (!poly_degree(f) || !poly_degree(g)) return;
      if (poly_degree(f) + poly_degree(g) > 3) return;
      element_ptr h = pbc_malloc(sizeof(*h));
      element_init(h, fx);
      element_mul(h, f, g);
      darray_append(prodlist, h);
      EXPECT(!poly_is_irred(h));
    }
예제 #12
0
파일: f_param.c 프로젝트: 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);
}
예제 #13
0
파일: f_param.c 프로젝트: 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);
}
예제 #14
0
파일: d_param.c 프로젝트: 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);
}
예제 #15
0
파일: d_param.c 프로젝트: 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);
}