コード例 #1
0
ファイル: e_param.c プロジェクト: Russ36363/pbc-thesis
static void e_miller_proj(element_t res, element_t P,
    element_ptr QR, element_ptr R,
    e_pairing_data_ptr p) {
  //collate divisions
  int n;
  element_t v, vd;
  element_t v1, vd1;
  element_t Z, Z1;
  element_t a, b, c;
  const element_ptr cca = curve_a_coeff(P);
  element_t e0, e1;
  const element_ptr e2 = a, e3 = b;
  element_t z, z2;
  int i;
  element_ptr Zx, Zy;
  const element_ptr Px = curve_x_coord(P);
  const element_ptr numx = curve_x_coord(QR);
  const element_ptr numy = curve_y_coord(QR);
  const element_ptr denomx = curve_x_coord(R);
  const element_ptr denomy = curve_y_coord(R);

  //convert Z from weighted projective (Jacobian) to affine
  //i.e. (X, Y, Z) --> (X/Z^2, Y/Z^3)
  //also sets z to 1
  void to_affine(void)
  {
    element_invert(z, z);
    element_square(e0, z);
    element_mul(Zx, Zx, e0);
    element_mul(e0, e0, z);
    element_mul(Zy, Zy, e0);
    element_set1(z);
    element_set1(z2);
  }
コード例 #2
0
void miller(element_t res, mpz_t q, element_t P, element_ptr Qx, element_ptr Qy) {
  int m;
  element_t v;
  element_t Z;
  element_t a, b, c;
  element_t t0;
  element_t e0;
  const element_ptr cca = curve_a_coeff(P);
  const element_ptr Px = curve_x_coord(P);
  const element_ptr Py = curve_y_coord(P);
  element_ptr Zx, Zy;

  void do_tangent(void) {
    // a = -(3 Zx^2 + cc->a)
    // b = 2 * Zy
    // c = -(2 Zy^2 + a Zx);

    element_square(a, Zx); mult1++;
    element_mul_si(a, a, 3); add1++; add1++; add1++;
    element_add(a, a, cca); add1++;
    element_neg(a, a);

    element_add(b, Zy, Zy); add1++;

    element_mul(t0, b, Zy); mult1++;
    element_mul(c, a, Zx); mult1++;
    element_add(c, c, t0); add1++;
    element_neg(c, c);

    d_miller_evalfn(e0, a, b, c, Qx, Qy);
    element_mul(v, v, e0); multk++;
  }
コード例 #3
0
ファイル: 19.c プロジェクト: blynn/pbc
static void miller(element_t res, element_t P, element_ptr QR, element_ptr R, int n) {
  // Collate divisions.
  mp_bitcnt_t m;
  element_t v, vd;
  element_t Z;
  element_t a, b, c;
  const element_ptr cca = curve_a_coeff(P);
  const element_ptr Px = curve_x_coord(P);
  const element_ptr Py = curve_y_coord(P);
  element_t e0, e1;
  mpz_t q;
  element_ptr Zx, Zy;
  const element_ptr numx = curve_x_coord(QR);
  const element_ptr numy = curve_y_coord(QR);
  const element_ptr denomx = curve_x_coord(R);
  const element_ptr denomy = curve_y_coord(R);

  #define do_vertical(e, edenom) {       \
    element_sub(e0, numx, Zx);           \
    element_mul((e), (e), e0);           \
                                         \
    element_sub(e0, denomx, Zx);         \
    element_mul((edenom), (edenom), e0); \
  }

  #define do_tangent(e, edenom) {                  \
    /*a = -slope_tangent(A.x, A.y);                \
      b = 1;                                       \
      c = -(A.y + a * A.x);                        \
      but we multiply by 2*A.y to avoid division*/ \
                                                   \
    /*a = -Ax * (Ax + Ax + Ax + twicea_2) - a_4;   \
      Common curves: a2 = 0 (and cc->a is a_4), so \
      a = -(3 Ax^2 + cc->a)                        \
      b = 2 * Ay                                   \
      c = -(2 Ay^2 + a Ax);                     */ \
                                                   \
    if (element_is0(Zy)) {                         \
      do_vertical((e), (edenom));                  \
    } else {                                       \
      element_square(a, Zx);                       \
      element_mul_si(a, a, 3);                     \
      element_add(a, a, cca);                      \
      element_neg(a, a);                           \
                                                   \
      element_add(b, Zy, Zy);                      \
                                                   \
      element_mul(e0, b, Zy);                      \
      element_mul(c, a, Zx);                       \
      element_add(c, c, e0);                       \
      element_neg(c, c);                           \
                                                   \
      element_mul(e0, a, numx);                    \
      element_mul(e1, b, numy);                    \
      element_add(e0, e0, e1);                     \
      element_add(e0, e0, c);                      \
      element_mul((e), (e), e0);                   \
                                                   \
      element_mul(e0, a, denomx);                  \
      element_mul(e1, b, denomy);                  \
      element_add(e0, e0, e1);                     \
      element_add(e0, e0, c);                      \
      element_mul((edenom), (edenom), e0);         \
    }                                              \
  }

  #define do_line(e, edenom) {         \
    if (!element_cmp(Zx, Px)) {        \
      if (!element_cmp(Zy, Py)) {      \
        do_tangent(e, edenom);         \
      } else {                         \
        do_vertical(e, edenom);        \
      }                                \
    } else {                           \
      element_sub(b, Px, Zx);          \
      element_sub(a, Zy, Py);          \
      element_mul(c, Zx, Py);          \
      element_mul(e0, Zy, Px);         \
      element_sub(c, c, e0);           \
                                       \
      element_mul(e0, a, numx);        \
      element_mul(e1, b, numy);        \
      element_add(e0, e0, e1);         \
      element_add(e0, e0, c);          \
      element_mul(e, e, e0);           \
                                       \
      element_mul(e0, a, denomx);      \
      element_mul(e1, b, denomy);      \
      element_add(e0, e0, e1);         \
      element_add(e0, e0, c);          \
      element_mul(edenom, edenom, e0); \
    }                                  \
  }

  element_init(a, res->field);
  element_init(b, res->field);
  element_init(c, res->field);
  element_init(e0, res->field);
  element_init(e1, res->field);

  element_init(v, res->field);
  element_init(vd, res->field);
  element_init(Z, P->field);

  element_set(Z, P);
  Zx = curve_x_coord(Z);
  Zy = curve_y_coord(Z);

  element_set1(v);
  element_set1(vd);

  mpz_init(q);
  mpz_set_ui(q, n);
  m = (mp_bitcnt_t)mpz_sizeinbase(q, 2);
  m = (m > 2 ? m - 2 : 0);

  for (;;) {
    element_square(v, v);
    element_square(vd, vd);
    do_tangent(v, vd);
    element_double(Z, Z);
    do_vertical(vd, v);

    if (mpz_tstbit(q, m)) {
      do_line(v, vd);
      element_add(Z, Z, P);
      if (m) {
        do_vertical(vd, v);
      }
    }
    if (!m) break;
    m--;
  }

  mpz_clear(q);

  element_invert(vd, vd);
  element_mul(res, v, vd);

  element_clear(v);
  element_clear(vd);
  element_clear(Z);
  element_clear(a);
  element_clear(b);
  element_clear(c);
  element_clear(e0);
  element_clear(e1);
  #undef do_vertical
  #undef do_tangent
  #undef do_line
}
コード例 #4
0
ファイル: e_param.c プロジェクト: Jason0218/JustPaly
static void e_miller_proj(element_t res, element_t P,
    element_ptr QR, element_ptr R,
    e_pairing_data_ptr p) {
  //collate divisions
  int n;
  element_t v, vd;
  element_t v1, vd1;
  element_t Z, Z1;
  element_t a, b, c;
  const element_ptr cca = curve_a_coeff(P);
  element_t e0, e1;
  const element_ptr e2 = a, e3 = b;
  element_t z, z2;
  int i;
  element_ptr Zx, Zy;
  const element_ptr Px = curve_x_coord(P);
  const element_ptr numx = curve_x_coord(QR);
  const element_ptr numy = curve_y_coord(QR);
  const element_ptr denomx = curve_x_coord(R);
  const element_ptr denomy = curve_y_coord(R);

  //convert Z from weighted projective (Jacobian) to affine
  //i.e. (X, Y, Z) --> (X/Z^2, Y/Z^3)
  //also sets z to 1
  #define to_affine() {      \
    element_invert(z, z);    \
    element_square(e0, z);   \
    element_mul(Zx, Zx, e0); \
    element_mul(e0, e0, z);  \
    element_mul(Zy, Zy, e0); \
    element_set1(z);         \
    element_set1(z2);        \
  }

  #define proj_double() {             \
    const element_ptr x = Zx;         \
    const element_ptr y = Zy;         \
    /* e0 = 3x^2 + (cc->a) z^4 */     \
    element_square(e0, x);            \
    /* element_mul_si(e0, e0, 3); */  \
    element_double(e1, e0);           \
    element_add(e0, e0, e1);          \
    element_square(e1, z2);           \
    element_mul(e1, e1, cca);         \
    element_add(e0, e0, e1);          \
                                      \
    /* z_out = 2 y z */               \
    element_mul(z, y, z);             \
    /* element_mul_si(z, z, 2); */    \
    element_double(z, z);             \
    element_square(z2, z);            \
                                      \
    /* e1 = 4 x y^2 */                \
    element_square(e2, y);            \
    element_mul(e1, x, e2);           \
    /* element_mul_si(e1, e1, 4); */  \
    element_double(e1, e1);           \
    element_double(e1, e1);           \
                                      \
    /* x_out = e0^2 - 2 e1 */         \
    /* element_mul_si(e3, e1, 2); */  \
    element_double(e3, e1);           \
    element_square(x, e0);            \
    element_sub(x, x, e3);            \
                                      \
    /* e2 = 8y^4 */                   \
    element_square(e2, e2);           \
    /* element_mul_si(e2, e2, 8); */  \
    element_double(e2, e2);           \
    element_double(e2, e2);           \
    element_double(e2, e2);           \
                                      \
    /* y_out = e0(e1 - x_out) - e2 */ \
    element_sub(e1, e1, x);           \
    element_mul(e0, e0, e1);          \
    element_sub(y, e0, e2);           \
  }

  #define do_tangent(e, edenom) {    \
    /* a = -(3x^2 + cca z^4) */      \
    /* b = 2 y z^3 */                \
    /* c = -(2 y^2 + x a) */         \
    /* a = z^2 a */                  \
    element_square(a, z2);           \
    element_mul(a, a, cca);          \
    element_square(b, Zx);           \
    /* element_mul_si(b, b, 3); */   \
    element_double(e0, b);           \
    element_add(b, b, e0);           \
    element_add(a, a, b);            \
    element_neg(a, a);               \
                                     \
    /* element_mul_si(e0, Zy, 2); */ \
    element_double(e0, Zy);          \
    element_mul(b, e0, z2);          \
    element_mul(b, b, z);            \
                                     \
    element_mul(c, Zx, a);           \
    element_mul(a, a, z2);           \
    element_mul(e0, e0, Zy);         \
    element_add(c, c, e0);           \
    element_neg(c, c);               \
                                     \
    element_mul(e0, a, numx);        \
    element_mul(e1, b, numy);        \
    element_add(e0, e0, e1);         \
    element_add(e0, e0, c);          \
    element_mul(e, e, e0);           \
                                     \
    element_mul(e0, a, denomx);      \
    element_mul(e1, b, denomy);      \
    element_add(e0, e0, e1);         \
    element_add(e0, e0, c);          \
    element_mul(edenom, edenom, e0); \
  }

  #define do_vertical(e, edenom, Ax) { \
    element_mul(e0, numx, z2);         \
    element_sub(e0, e0, Ax);           \
    element_mul(e, e, e0);             \
                                       \
    element_mul(e0, denomx, z2);       \
    element_sub(e0, e0, Ax);           \
    element_mul(edenom, edenom, e0);   \
  }

  #define do_line(e, edenom, A, B) {   \
    element_ptr Ax = curve_x_coord(A); \
    element_ptr Ay = curve_y_coord(A); \
    element_ptr Bx = curve_x_coord(B); \
    element_ptr By = curve_y_coord(B); \
                                       \
    element_sub(b, Bx, Ax);            \
    element_sub(a, Ay, By);            \
    element_mul(c, Ax, By);            \
    element_mul(e0, Ay, Bx);           \
    element_sub(c, c, e0);             \
                                       \
    element_mul(e0, a, numx);          \
    element_mul(e1, b, numy);          \
    element_add(e0, e0, e1);           \
    element_add(e0, e0, c);            \
    element_mul(e, e, e0);             \
                                       \
    element_mul(e0, a, denomx);        \
    element_mul(e1, b, denomy);        \
    element_add(e0, e0, e1);           \
    element_add(e0, e0, c);            \
    element_mul(edenom, edenom, e0);   \
  }

  element_init(a, res->field);
  element_init(b, res->field);
  element_init(c, res->field);
  element_init(e0, res->field);
  element_init(e1, res->field);
  element_init(z, res->field);
  element_init(z2, res->field);
  element_set1(z);
  element_set1(z2);

  element_init(v, res->field);
  element_init(vd, res->field);
  element_init(v1, res->field);
  element_init(vd1, res->field);
  element_init(Z, P->field);
  element_init(Z1, P->field);

  element_set(Z, P);
  Zx = curve_x_coord(Z);
  Zy = curve_y_coord(Z);

  element_set1(v);
  element_set1(vd);
  element_set1(v1);
  element_set1(vd1);

  n = p->exp1;
  for (i=0; i<n; i++) {
    element_square(v, v);
    element_square(vd, vd);
    do_tangent(v, vd);
    proj_double();
    do_vertical(vd, v, Zx);
  }
  to_affine();
  if (p->sign1 < 0) {
    element_set(v1, vd);
    element_set(vd1, v);
    do_vertical(vd1, v1, Zx);
    element_neg(Z1, Z);
  } else {
    element_set(v1, v);
    element_set(vd1, vd);
    element_set(Z1, Z);
  }
  n = p->exp2;
  for (; i<n; i++) {
    element_square(v, v);
    element_square(vd, vd);
    do_tangent(v, vd);
    proj_double();
    do_vertical(vd, v, Zx);
  }
  to_affine();
  element_mul(v, v, v1);
  element_mul(vd, vd, vd1);
  do_line(v, vd, Z, Z1);
  element_add(Z, Z, Z1);
  do_vertical(vd, v, Zx);

  if (p->sign0 > 0) {
    do_vertical(v, vd, Px);
  }

  element_invert(vd, vd);
  element_mul(res, v, vd);

  element_clear(v);
  element_clear(vd);
  element_clear(v1);
  element_clear(vd1);
  element_clear(z);
  element_clear(z2);
  element_clear(Z);
  element_clear(Z1);
  element_clear(a);
  element_clear(b);
  element_clear(c);
  element_clear(e0);
  element_clear(e1);
  #undef to_affine
  #undef proj_double
  #undef do_tangent
  #undef do_vertical
  #undef do_line
}
コード例 #5
0
ファイル: e_param.c プロジェクト: Jason0218/JustPaly
// in1, in2 are from E(F_q), out from F_q^2.
// Pairing via elliptic nets (see Stange).
static void e_pairing_ellnet(element_ptr out, element_ptr in1, element_ptr in2,
    pairing_t pairing) {
  const element_ptr a = curve_a_coeff(in1);
  const element_ptr b = curve_b_coeff(in1);

  element_ptr x = curve_x_coord(in1);
  element_ptr y = curve_y_coord(in1);

  element_ptr x2 = curve_x_coord(in2);
  element_ptr y2 = curve_y_coord(in2);

  //notation: cmi means c_{k-i}, ci means c_{k+i}
  element_t cm3, cm2, cm1, c0, c1, c2, c3, c4;
  element_t dm1, d0, d1;
  element_t A, B, C;

  element_init_same_as(cm3, x);
  element_init_same_as(cm2, x);
  element_init_same_as(cm1, x);
  element_init_same_as(c0, x);
  element_init_same_as(c1, x);
  element_init_same_as(c2, x);
  element_init_same_as(c3, x);
  element_init_same_as(c4, x);
  element_init_same_as(C, x);

  element_init_same_as(dm1, out);
  element_init_same_as(d0, out);
  element_init_same_as(d1, out);
  element_init_same_as(A, x);
  element_init_same_as(B, out);

  // c1 = 2y
  // cm3 = -2y
  element_double(c1, y);
  element_neg(cm3, c1);

  //use c0, cm1, cm2, C, c4 as temp variables for now
  //compute c3, c2
  element_square(cm2, x);
  element_square(C, cm2);
  element_mul(cm1, b, x);
  element_double(cm1, cm1);
  element_square(c4, a);

  element_mul(c2, cm1, cm2);
  element_double(c2, c2);
  element_mul(c0, a, C);
  element_add(c2, c2, c0);
  element_mul(c0, c4, cm2);
  element_sub(c2, c2, c0);
  element_double(c0, c2);
  element_double(c0, c0);
  element_add(c2, c2, c0);

  element_mul(c0, cm1, a);
  element_square(c3, b);
  element_double(c3, c3);
  element_double(c3, c3);
  element_add(c0, c0, c3);
  element_double(c0, c0);
  element_mul(c3, a, c4);
  element_add(c0, c0, c3);
  element_sub(c2, c2, c0);
  element_mul(c0, cm2, C);
  element_add(c3, c0, c2);
  element_mul(c3, c3, c1);
  element_double(c3, c3);

  element_mul(c0, a, cm2);
  element_add(c0, c0, cm1);
  element_double(c0, c0);
  element_add(c0, c0, C);
  element_double(c2, c0);
  element_add(c0, c0, c2);
  element_sub(c2, c0, c4);

  // c0 = 1
  // cm2 = -1
  element_set1(c0);
  element_neg(cm2, c0);

  // c4 = c_5 = c_2^3 c_4 - c_3^3 = c1^3 c3 - c2^3
  element_square(C, c1);
  element_mul(c4, C, c1);
  element_mul(c4, c4, c3);
  element_square(C, c2);
  element_mul(C, C, c2);
  element_sub(c4, c4, C);

  //compute A, B, d1 (which is d_2 since k = 1)
  element_sub(A, x, x2);
  element_double(C, x);
  element_add(C, C, x2);
  element_square(cm1, A);
  element_mul(cm1, C, cm1);
  element_add(d1, y, y2);
  element_square(d1, d1);
  element_sub(B, cm1, d1);
  element_invert(B, B);
  element_invert(A, A);

  element_sub(d1, y, y2);
  element_mul(d1, d1, A);
  element_square(d1, d1);
  element_sub(d1, C, d1);

  // cm1 = 0
  // C = (2y)^-1
  element_set0(cm1);
  element_invert(C, c1);

  element_set1(dm1);
  element_set1(d0);

  element_t sm2, sm1;
  element_t s0, s1, s2, s3;
  element_t tm2, tm1;
  element_t t0, t1, t2, t3;
  element_t e0, e1;
  element_t u, v;

  element_init_same_as(sm2, x);
  element_init_same_as(sm1, x);
  element_init_same_as(s0, x);
  element_init_same_as(s1, x);
  element_init_same_as(s2, x);
  element_init_same_as(s3, x);

  element_init_same_as(tm2, x);
  element_init_same_as(tm1, x);
  element_init_same_as(t0, x);
  element_init_same_as(t1, x);
  element_init_same_as(t2, x);
  element_init_same_as(t3, x);

  element_init_same_as(e0, x);
  element_init_same_as(e1, x);

  element_init_same_as(u, d0);
  element_init_same_as(v, d0);

  int m = mpz_sizeinbase(pairing->r, 2) - 2;
  for (;;) {
    element_square(sm2, cm2);
    element_square(sm1, cm1);
    element_square(s0, c0);
    element_square(s1, c1);
    element_square(s2, c2);
    element_square(s3, c3);

    element_mul(tm2, cm3, cm1);
    element_mul(tm1, cm2, c0);
    element_mul(t0, cm1, c1);
    element_mul(t1, c0, c2);
    element_mul(t2, c1, c3);
    element_mul(t3, c2, c4);

    element_square(u, d0);
    element_mul(v, dm1, d1);

    if (mpz_tstbit(pairing->r, m)) {
      //double-and-add
      element_mul(e0, t0, sm2);
      element_mul(e1, tm2, s0);
      element_sub(cm3, e0, e1);
      element_mul(cm3, cm3, C);

      element_mul(e0, t0, sm1);
      element_mul(e1, tm1, s0);
      element_sub(cm2, e0, e1);

      element_mul(e0, t1, sm1);
      element_mul(e1, tm1, s1);
      element_sub(cm1, e0, e1);
      element_mul(cm1, cm1, C);

      element_mul(e0, t1, s0);
      element_mul(e1, t0, s1);
      element_sub(c0, e0, e1);

      element_mul(e0, t2, s0);
      element_mul(e1, t0, s2);
      element_sub(c1, e0, e1);
      element_mul(c1, c1, C);

      element_mul(e0, t2, s1);
      element_mul(e1, t1, s2);
      element_sub(c2, e0, e1);

      element_mul(e0, t3, s1);
      element_mul(e1, t1, s3);
      element_sub(c3, e0, e1);
      element_mul(c3, c3, C);

      element_mul(e0, t3, s2);
      element_mul(e1, t2, s3);
      element_sub(c4, e0, e1);

      element_mul(out, u, t0);
      element_mul(dm1, v, s0);
      element_sub(dm1, dm1, out);

      element_mul(out, u, t1);
      element_mul(d0, v, s1);
      element_sub(d0, d0, out);
      element_mul(d0, d0, A);

      element_mul(out, u, t2);
      element_mul(d1, v, s2);
      element_sub(d1, d1, out);
      element_mul(d1, d1, B);
    } else {
      //double
      element_mul(e0, tm1, sm2);
      element_mul(e1, tm2, sm1);
      element_sub(cm3, e0, e1);

      element_mul(e0, t0, sm2);
      element_mul(e1, tm2, s0);
      element_sub(cm2, e0, e1);
      element_mul(cm2, cm2, C);

      element_mul(e0, t0, sm1);
      element_mul(e1, tm1, s0);
      element_sub(cm1, e0, e1);

      element_mul(e0, t1, sm1);
      element_mul(e1, tm1, s1);
      element_sub(c0, e0, e1);
      element_mul(c0, c0, C);

      element_mul(e0, t1, s0);
      element_mul(e1, t0, s1);
      element_sub(c1, e0, e1);

      element_mul(e0, t2, s0);
      element_mul(e1, t0, s2);
      element_sub(c2, e0, e1);
      element_mul(c2, c2, C);

      element_mul(e0, t2, s1);
      element_mul(e1, t1, s2);
      element_sub(c3, e0, e1);

      element_mul(e0, t3, s1);
      element_mul(e1, t1, s3);
      element_sub(c4, e0, e1);
      element_mul(c4, c4, C);

      element_mul(out, u, tm1);
      element_mul(dm1, v, sm1);
      element_sub(dm1, dm1, out);

      element_mul(out, u, t0);
      element_mul(d0, v, s0);
      element_sub(d0, d0, out);

      element_mul(out, u, t1);
      element_mul(d1, v, s1);
      element_sub(d1, d1, out);
      element_mul(d1, d1, A);
    }
    if (!m) break;
    m--;
  }
  element_invert(c1, c1);
  element_mul(d1, d1, c1);

  element_pow_mpz(out, d1, pairing->phikonr);

  element_clear(dm1);
  element_clear(d0);
  element_clear(d1);

  element_clear(cm3);
  element_clear(cm2);
  element_clear(cm1);
  element_clear(c0);
  element_clear(c1);
  element_clear(c2);
  element_clear(c3);
  element_clear(c4);

  element_clear(sm2);
  element_clear(sm1);
  element_clear(s0);
  element_clear(s1);
  element_clear(s2);
  element_clear(s3);

  element_clear(tm2);
  element_clear(tm1);
  element_clear(t0);
  element_clear(t1);
  element_clear(t2);
  element_clear(t3);

  element_clear(e0);
  element_clear(e1);
  element_clear(A);
  element_clear(B);
  element_clear(C);
  element_clear(u);
  element_clear(v);
}
コード例 #6
0
ファイル: e_param.c プロジェクト: Jason0218/JustPaly
static void e_miller_affine(element_t res, element_t P,
    element_ptr QR, element_ptr R,
    e_pairing_data_ptr p) {
  //collate divisions
  int n;
  element_t v, vd;
  element_t v1, vd1;
  element_t Z, Z1;
  element_t a, b, c;
  element_t e0, e1;
  const element_ptr Px = curve_x_coord(P);
  const element_ptr cca = curve_a_coeff(P);
  element_ptr Zx, Zy;
  int i;
  const element_ptr numx = curve_x_coord(QR);
  const element_ptr numy = curve_y_coord(QR);
  const element_ptr denomx = curve_x_coord(R);
  const element_ptr denomy = curve_y_coord(R);

  #define do_vertical(e, edenom, Ax) { \
    element_sub(e0, numx, Ax);         \
    element_mul(e, e, e0);             \
                                       \
    element_sub(e0, denomx, Ax);       \
    element_mul(edenom, edenom, e0);   \
  }

  #define do_tangent(e, edenom) {                      \
    /* a = -slope_tangent(A.x, A.y); */                \
    /* b = 1; */                                       \
    /* c = -(A.y + a * A.x); */                        \
    /* but we multiply by 2*A.y to avoid division */   \
                                                       \
    /* a = -Ax * (Ax + Ax + Ax + twicea_2) - a_4; */   \
    /* Common curves: a2 = 0 (and cc->a is a_4), so */ \
    /* a = -(3 Ax^2 + cc->a) */                        \
    /* b = 2 * Ay */                                   \
    /* c = -(2 Ay^2 + a Ax); */                        \
                                                       \
    element_square(a, Zx);                             \
    element_mul_si(a, a, 3);                           \
    element_add(a, a, cca);                            \
    element_neg(a, a);                                 \
                                                       \
    element_add(b, Zy, Zy);                            \
                                                       \
    element_mul(e0, b, Zy);                            \
    element_mul(c, a, Zx);                             \
    element_add(c, c, e0);                             \
    element_neg(c, c);                                 \
                                                       \
    element_mul(e0, a, numx);                          \
    element_mul(e1, b, numy);                          \
    element_add(e0, e0, e1);                           \
    element_add(e0, e0, c);                            \
    element_mul(e, e, e0);                             \
                                                       \
    element_mul(e0, a, denomx);                        \
    element_mul(e1, b, denomy);                        \
    element_add(e0, e0, e1);                           \
    element_add(e0, e0, c);                            \
    element_mul(edenom, edenom, e0);                   \
  }

  #define do_line(e, edenom, A, B) {   \
    element_ptr Ax = curve_x_coord(A); \
    element_ptr Ay = curve_y_coord(A); \
    element_ptr Bx = curve_x_coord(B); \
    element_ptr By = curve_y_coord(B); \
                                       \
    element_sub(b, Bx, Ax);            \
    element_sub(a, Ay, By);            \
    element_mul(c, Ax, By);            \
    element_mul(e0, Ay, Bx);           \
    element_sub(c, c, e0);             \
                                       \
    element_mul(e0, a, numx);          \
    element_mul(e1, b, numy);          \
    element_add(e0, e0, e1);           \
    element_add(e0, e0, c);            \
    element_mul(e, e, e0);             \
                                       \
    element_mul(e0, a, denomx);        \
    element_mul(e1, b, denomy);        \
    element_add(e0, e0, e1);           \
    element_add(e0, e0, c);            \
    element_mul(edenom, edenom, e0);   \
  }

  element_init(a, res->field);
  element_init(b, res->field);
  element_init(c, res->field);
  element_init(e0, res->field);
  element_init(e1, res->field);

  element_init(v, res->field);
  element_init(vd, res->field);
  element_init(v1, res->field);
  element_init(vd1, res->field);
  element_init(Z, P->field);
  element_init(Z1, P->field);

  element_set(Z, P);
  Zx = curve_x_coord(Z);
  Zy = curve_y_coord(Z);

  element_set1(v);
  element_set1(vd);
  element_set1(v1);
  element_set1(vd1);

  n = p->exp1;
  for (i=0; i<n; i++) {
    element_square(v, v);
    element_square(vd, vd);
    do_tangent(v, vd);
    element_double(Z, Z);
    do_vertical(vd, v, Zx);
  }
  if (p->sign1 < 0) {
    element_set(v1, vd);
    element_set(vd1, v);
    do_vertical(vd1, v1, Zx);
    element_neg(Z1, Z);
  } else {
    element_set(v1, v);
    element_set(vd1, vd);
    element_set(Z1, Z);
  }
  n = p->exp2;
  for (; i<n; i++) {
    element_square(v, v);
    element_square(vd, vd);
    do_tangent(v, vd);
    element_double(Z, Z);
    do_vertical(vd, v, Zx);
  }
  element_mul(v, v, v1);
  element_mul(vd, vd, vd1);
  do_line(v, vd, Z, Z1);
  element_add(Z, Z, Z1);
  do_vertical(vd, v, Zx);

  if (p->sign0 > 0) {
    do_vertical(v, vd, Px);
  }

  element_invert(vd, vd);
  element_mul(res, v, vd);

  element_clear(v);
  element_clear(vd);
  element_clear(v1);
  element_clear(vd1);
  element_clear(Z);
  element_clear(Z1);
  element_clear(a);
  element_clear(b);
  element_clear(c);
  element_clear(e0);
  element_clear(e1);
  #undef do_vertical
  #undef do_tangent
  #undef do_line
}
コード例 #7
0
ファイル: d_param.c プロジェクト: blynn/pbc
static void d_pairing_pp_init(pairing_pp_t p, element_ptr in1, pairing_t pairing) {
  element_ptr P = in1;
  const element_ptr Px = curve_x_coord(P);
  const element_ptr Py = curve_y_coord(P);
  element_t Z;
  mp_bitcnt_t m;
  pptr info = pairing->data;
  element_t t0;
  element_t a, b, c;
  field_ptr Fq = info->Fq;
  pp_coeff_t *coeff;
  mpz_ptr q = pairing->r;
  pp_coeff_ptr pp;
  const element_ptr cca = curve_a_coeff(P);
  element_ptr Zx;
  element_ptr Zy;

  #define store_abc() {      \
    element_init(pp->a, Fq); \
    element_init(pp->b, Fq); \
    element_init(pp->c, Fq); \
    element_set(pp->a, a);   \
    element_set(pp->b, b);   \
    element_set(pp->c, c);   \
    pp++;                    \
  }

  #define do_tangent() {                               \
    /* a = -slope_tangent(Z.x, Z.y); */                \
    /* b = 1; */                                       \
    /* c = -(Z.y + a * Z.x); */                        \
    /* but we multiply by 2*Z.y to avoid division. */  \
                                                       \
    /* a = -Zx * (3 Zx + twicea_2) - a_4; */           \
    /* Common curves: a2 = 0 (and cc->a is a_4), so */ \
    /* a = -(3 Zx^2 + cc->a) */                        \
    /* b = 2 * Zy */                                   \
    /* c = -(2 Zy^2 + a Zx); */                        \
                                                       \
    element_square(a, Zx);                             \
    element_double(t0, a);                             \
    element_add(a, a, t0);                             \
    element_add(a, a, cca);                            \
    element_neg(a, a);                                 \
                                                       \
    element_add(b, Zy, Zy);                            \
                                                       \
    element_mul(t0, b, Zy);                            \
    element_mul(c, a, Zx);                             \
    element_add(c, c, t0);                             \
    element_neg(c, c);                                 \
                                                       \
    store_abc();                                       \
  }

  #define do_line() {                                       \
    /* a = -(B.y - A.y) / (B.x - A.x); */                   \
    /* b = 1; */                                            \
    /* c = -(A.y + a * A.x); */                             \
    /* but we'll multiply by B.x - A.x to avoid division */ \
                                                            \
    element_sub(b, Px, Zx);                                 \
    element_sub(a, Zy, Py);                                 \
    element_mul(t0, b, Zy);                                 \
    element_mul(c, a, Zx);                                  \
    element_add(c, c, t0);                                  \
    element_neg(c, c);                                      \
                                                            \
    store_abc();                                            \
  }

  element_init(Z, P->field);
  element_set(Z, P);
  Zx = curve_x_coord(Z);
  Zy = curve_y_coord(Z);

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

  m = (mp_bitcnt_t)mpz_sizeinbase(q, 2);
  m = (m > 2 ? m - 2 : 0);
  p->data = pbc_malloc(sizeof(pp_coeff_t) * 2 * m);
  coeff = (pp_coeff_t *) p->data;
  pp = coeff[0];

  for(;;) {
    do_tangent();

    if (!m) break;

    element_double(Z, Z);
    if (mpz_tstbit(q, m)) {
      do_line();
      element_add(Z, Z, P);
    }
    m--;
  }

  element_clear(t0);
  element_clear(a);
  element_clear(b);
  element_clear(c);
  element_clear(Z);
  #undef store_abc
  #undef do_tangent
  #undef do_line
}
コード例 #8
0
ファイル: d_param.c プロジェクト: blynn/pbc
//do many millers at one time with affine coordinates.
static void cc_millers_no_denom_affine(element_t res, mpz_t q, element_t P[],
    element_t Qx[], element_t Qy[], int n_prod) {
  mp_bitcnt_t m;
  int i;
  element_t v;
  element_t a, b, c;
  element_t t0;
  element_t e0;
  const element_ptr cca = curve_a_coeff(P[0]);
  element_ptr Px, Py;
  element_t* Z = pbc_malloc(sizeof(element_t)*n_prod);
  element_ptr Zx, Zy;

  /* TODO: when exactly is this not needed?
  void do_vertical() {
    mapbase(e0, Z->x);
    element_sub(e0, Qx, e0);
    element_mul(v, v, e0);
  }
  */

  #define do_tangents() {                         \
    /* a = -(3 Zx^2 + cc->a) */                   \
    /* b = 2 * Zy */                              \
    /* c = -(2 Zy^2 + a Zx); */                   \
    for(i=0; i<n_prod; i++){                      \
      Px = curve_x_coord(P[i]);                   \
      Py = curve_y_coord(P[i]);                   \
      Zx = curve_x_coord(Z[i]);                   \
      Zy = curve_y_coord(Z[i]);                   \
                                                  \
      element_square(a, Zx);                      \
      element_mul_si(a, a, 3);                    \
      element_add(a, a, cca);                     \
      element_neg(a, a);                          \
                                                  \
      element_add(b, Zy, Zy);                     \
                                                  \
      element_mul(t0, b, Zy);                     \
      element_mul(c, a, Zx);                      \
      element_add(c, c, t0);                      \
      element_neg(c, c);                          \
                                                  \
      d_miller_evalfn(e0, a, b, c, Qx[i], Qy[i]); \
      element_mul(v, v, e0);                      \
    }                                             \
  }

  #define do_lines() {                                    \
    /* a = -(B.y - A.y) / (B.x - A.x); */                 \
    /* b = 1; */                                          \
    /* c = -(A.y + a * A.x); */                           \
    /* but we multiply by B.x - A.x to avoid division. */ \
    for(i=0; i<n_prod; i++){                              \
      Px = curve_x_coord(P[i]);                           \
      Py = curve_y_coord(P[i]);                           \
      Zx = curve_x_coord(Z[i]);                           \
      Zy = curve_y_coord(Z[i]);                           \
                                                          \
      element_sub(b, Px, Zx);                             \
      element_sub(a, Zy, Py);                             \
      element_mul(t0, b, Zy);                             \
      element_mul(c, a, Zx);                              \
      element_add(c, c, t0);                              \
      element_neg(c, c);                                  \
                                                          \
      d_miller_evalfn(e0, a, b, c, Qx[i], Qy[i]);         \
      element_mul(v, v, e0);                              \
    }                                                     \
  }

  Px= curve_x_coord(P[0]); //temporally used to initial a,b, c and etc.
  element_init(a, Px->field);
  element_init(b, a->field);
  element_init(c, a->field);
  element_init(t0, a->field);
  element_init(e0, res->field);

  element_init(v, res->field);
  for(i=0; i<n_prod; i++){
    element_init(Z[i], P[i]->field);
    element_set(Z[i], P[i]);
  }

  element_set1(v);
  m = (mp_bitcnt_t)mpz_sizeinbase(q, 2);
  m = (m > 2 ? m - 2 : 0);

  for(;;) {
    do_tangents();

    if (!m) break;
    element_multi_double(Z, Z, n_prod); //Z_i=Z_i+Z_i for all i.

    if (mpz_tstbit(q, m)) {
      do_lines();
      element_multi_add(Z, Z, P, n_prod); //Z_i=Z_i+P_i for all i.
    }
    m--;
    element_square(v, v);
  }

  element_set(res, v);

  element_clear(v);
  for(i=0; i<n_prod; i++){
    element_clear(Z[i]);
  }
  pbc_free(Z);
  element_clear(a);
  element_clear(b);
  element_clear(c);
  element_clear(t0);
  element_clear(e0);
  #undef do_tangents
  #undef do_lines
}
コード例 #9
0
ファイル: d_param.c プロジェクト: blynn/pbc
// Same as above, but with affine coordinates.
static void cc_miller_no_denom_affine(element_t res, mpz_t q, element_t P,
    element_ptr Qx, element_ptr Qy) {
  mp_bitcnt_t m;
  element_t v;
  element_t Z;
  element_t a, b, c;
  element_t t0;
  element_t e0;
  const element_ptr cca = curve_a_coeff(P);
  const element_ptr Px = curve_x_coord(P);
  const element_ptr Py = curve_y_coord(P);
  element_ptr Zx, Zy;

  /* TODO: when exactly is this not needed?
  void do_vertical() {
    mapbase(e0, Z->x);
    element_sub(e0, Qx, e0);
    element_mul(v, v, e0);
  }
  */

  #define do_tangent() {                  \
    /* a = -(3 Zx^2 + cc->a) */           \
    /* b = 2 * Zy */                      \
    /* c = -(2 Zy^2 + a Zx); */           \
                                          \
    element_square(a, Zx);                \
    element_mul_si(a, a, 3);              \
    element_add(a, a, cca);               \
    element_neg(a, a);                    \
                                          \
    element_add(b, Zy, Zy);               \
                                          \
    element_mul(t0, b, Zy);               \
    element_mul(c, a, Zx);                \
    element_add(c, c, t0);                \
    element_neg(c, c);                    \
                                          \
    d_miller_evalfn(e0, a, b, c, Qx, Qy); \
    element_mul(v, v, e0);                \
  }

  #define do_line() {                                     \
    /* a = -(B.y - A.y) / (B.x - A.x); */                 \
    /* b = 1; */                                          \
    /* c = -(A.y + a * A.x); */                           \
    /* but we multiply by B.x - A.x to avoid division. */ \
                                                          \
    element_sub(b, Px, Zx);                               \
    element_sub(a, Zy, Py);                               \
    element_mul(t0, b, Zy);                               \
    element_mul(c, a, Zx);                                \
    element_add(c, c, t0);                                \
    element_neg(c, c);                                    \
                                                          \
    d_miller_evalfn(e0, a, b, c, Qx, Qy);                 \
    element_mul(v, v, e0);                                \
  }

  element_init(a, Px->field);
  element_init(b, a->field);
  element_init(c, a->field);
  element_init(t0, a->field);
  element_init(e0, res->field);

  element_init(v, res->field);
  element_init(Z, P->field);

  element_set(Z, P);
  Zx = curve_x_coord(Z);
  Zy = curve_y_coord(Z);

  element_set1(v);
  m = (mp_bitcnt_t)mpz_sizeinbase(q, 2);
  m = (m > 2 ? m - 2 : 0);

  for(;;) {
    do_tangent();

    if (!m) break;

    element_double(Z, Z);
    if (mpz_tstbit(q, m)) {
      do_line();
      element_add(Z, Z, P);
    }
    m--;
    element_square(v, v);
  }

  element_set(res, v);

  element_clear(v);
  element_clear(Z);
  element_clear(a);
  element_clear(b);
  element_clear(c);
  element_clear(t0);
  element_clear(e0);
  #undef do_tangent
  #undef do_line
}
コード例 #10
0
ファイル: d_param.c プロジェクト: blynn/pbc
// Miller's algorithm, assuming we can ignore the denominator. We can do this
// with careful group selection when the embedding degree is even. See thesis.
// This version uses projective coordinates, which don't seem much faster.
static void cc_miller_no_denom_proj(element_t res, mpz_t q, element_t P,
    element_ptr Qx, element_ptr Qy) {
  mp_bitcnt_t m;
  element_t v;
  element_t Z;
  element_t a, b, c;
  element_t t0, t1;
  element_ptr t2 = a, t3 = b, t4 = c;
  element_t e0;
  element_t z, z2;
  element_ptr Zx, Zy;
  const element_ptr curve_a = curve_a_coeff(P);
  const element_ptr Px = curve_x_coord(P);
  const element_ptr Py = curve_y_coord(P);

  #define proj_double() {             \
    /* t0 = 3x^2 + (curve_a) z^4 */   \
    element_square(t0, Zx);           \
    /* element_mul_si(t0, t0, 3); */  \
    element_double(t1, t0);           \
    element_add(t0, t0, t1);          \
    element_square(t1, z2);           \
    element_mul(t1, t1, curve_a);     \
    element_add(t0, t0, t1);          \
                                      \
    /* z_out = 2 y z */               \
    element_mul(z, Zy, z);            \
    /* element_mul_si(z, z, 2); */    \
    element_double(z, z);             \
    element_square(z2, z);            \
                                      \
    /* t1 = 4 x y^2 */                \
    element_square(t2, Zy);           \
    element_mul(t1, Zx, t2);          \
    /* element_mul_si(t1, t1, 4); */  \
    element_double(t1, t1);           \
    element_double(t1, t1);           \
                                      \
    /* x_out = t0^2 - 2 t1 */         \
    /* element_mul_si(t3, t1, 2); */  \
    element_double(t3, t1);           \
    element_square(Zx, t0);           \
    element_sub(Zx, Zx, t3);          \
                                      \
    /* t2 = 8y^4 */                   \
    element_square(t2, t2);           \
    /* element_mul_si(t2, t2, 8); */  \
    element_double(t2, t2);           \
    element_double(t2, t2);           \
    element_double(t2, t2);           \
                                      \
    /* y_out = t0(t1 - x_out) - t2 */ \
    element_sub(t1, t1, Zx);          \
    element_mul(t0, t0, t1);          \
    element_sub(Zy, t0, t2);          \
  }

  #define proj_mixin() {                        \
    /* t2 = Px z^2 */                           \
    element_mul(t2, z2, Px);                    \
                                                \
    /* t3 = Zx - t2 */                          \
    element_sub(t3, Zx, t2);                    \
                                                \
    /* t0 = Py z^3 */                           \
    element_mul(t0, z2, Py);                    \
    element_mul(t0, t0, z);                     \
                                                \
    /* t1 = Zy - t0 */                          \
    element_sub(t1, Zy, t0);                    \
                                                \
    /* e7 = Zx + t2, use t2 to double for e7 */ \
    element_add(t2, Zx, t2);                    \
                                                \
    /* e8 = Zy + t0, use t0 to double for e8 */ \
    element_add(t0, Zy, t0);                    \
                                                \
    /* z = z t3 */                              \
    element_mul(z, z, t3);                      \
    element_square(z2, z);                      \
                                                \
    /* Zx = t1^2 - e7 t3^2 */                   \
    /* t3 now holds t3^3, */                    \
    /* t4 holds e7 t3^2. */                     \
    element_square(t4, t3);                     \
    element_mul(t3, t4, t3);                    \
    element_square(Zx, t1);                     \
    element_mul(t4, t2, t4);                    \
    element_sub(Zx, Zx, t4);                    \
                                                \
    /* t4 = e7 t3^2 - 2 Zx */                   \
    element_sub(t4, t4, Zx);                    \
    element_sub(t4, t4, Zx);                    \
                                                \
    /* Zy = (t4 t1 - e8 t3^3)/2 */              \
    element_mul(t4, t4, t1);                    \
    element_mul(t0, t0, t3);                    \
    element_sub(t4, t4, t0);                    \
    element_halve(Zy, t4);                      \
  }

  #define do_tangent() {                  \
    /* a = -(3x^2 + cca z^4) */           \
    /* b = 2 y z^3 */                     \
    /* c = -(2 y^2 + x a) */              \
    /* a = z^2 a */                       \
    element_square(a, z2);                \
    element_mul(a, a, curve_a);           \
    element_square(b, Zx);                \
    /* element_mul_si(b, b, 3); */        \
    element_double(t0, b);                \
    element_add(b, b, t0);                \
    element_add(a, a, b);                 \
    element_neg(a, a);                    \
                                          \
    element_mul(b, z, z2);                \
    element_mul(b, b, Zy);                \
    element_mul_si(b, b, 2);              \
                                          \
    element_mul(c, Zx, a);                \
    element_mul(a, a, z2);                \
    element_square(t0, Zy);               \
    element_mul_si(t0, t0, 2);            \
    element_add(c, c, t0);                \
    element_neg(c, c);                    \
                                          \
    d_miller_evalfn(e0, a, b, c, Qx, Qy); \
    element_mul(v, v, e0);                \
  }

  #define do_line() {                     \
    /* a = -(Py z^3 - Zy) */              \
    /* b = Px z^3 - Zx z */               \
    /* c = Zx z Py - Zy Px; */            \
                                          \
    element_mul(t0, Zx, z);               \
    element_mul(t1, z2, z);               \
                                          \
    element_mul(a, Py, t1);               \
    element_sub(a, Zy, a);                \
                                          \
    element_mul(b, Px, t1);               \
    element_sub(b, b, t0);                \
                                          \
    element_mul(t0, t0, Py);              \
    element_mul(c, Zy, Px);               \
    element_sub(c, t0, c);                \
                                          \
    d_miller_evalfn(e0, a, b, c, Qx, Qy); \
    element_mul(v, v, e0);                \
  }

  element_init(a, Px->field);
  element_init(b, a->field);
  element_init(c, a->field);
  element_init(t0, a->field);
  element_init(t1, a->field);
  element_init(e0, res->field);
  element_init(z, a->field);
  element_init(z2, a->field);
  element_set1(z);
  element_set1(z2);

  element_init(v, res->field);
  element_init(Z, P->field);

  element_set(Z, P);
  Zx = curve_x_coord(Z);
  Zy = curve_x_coord(Z);

  element_set1(v);
  m = (mp_bitcnt_t)mpz_sizeinbase(q, 2);
  m = (m > 2 ? m - 2 : 0);

  for(;;) {
    do_tangent();
    if (!m) break;
    proj_double();
    if (mpz_tstbit(q, m)) {
      do_line();
      proj_mixin();
    }
    m--;
    element_square(v, v);
  }

  element_set(res, v);

  element_clear(v);
  element_clear(Z);
  element_clear(a);
  element_clear(b);
  element_clear(c);
  element_clear(t0);
  element_clear(t1);
  element_clear(e0);
  element_clear(z);
  element_clear(z2);
  #undef proj_double
  #undef proj_mixin
  #undef do_tangent
  #undef do_line
}