コード例 #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
ファイル: 59.c プロジェクト: Russ36363/pbc-thesis
void millertate(element_t z, element_t P, element_t Q)
{
    element_t Z;
    element_t z0;

    element_init_same_as(Z, P);
    element_init_same_as(z0, z);

    element_set(Z, P);

    do_tangent(z, Z, Q);

    element_double(Z, Z);

    do_vert(z0, Z, Q);
    element_div(z, z, z0);

    element_printf("presquare: z = %B\n", z);

    element_square(z, z);

    element_printf("square: z = %B\n", z);

    do_tangent(z0, Z, Q);
    element_mul(z, z, z0);

    element_clear(z0);
    element_clear(Z);
}
コード例 #3
0
ファイル: 59.c プロジェクト: Russ36363/pbc-thesis
void miller(element_t z, element_t PR, element_t R, element_t P, element_t Q)
{
    int m = mpz_sizeinbase(order, 2) - 2;

    element_t Z;
    element_t z1;
    element_t x1;
    element_init_same_as(Z, PR);

    element_set(Z, P);
    element_set1(z);
    element_init_same_as(z1, z);
    element_init_same_as(x1, z);

    do_vert(x1, PR, Q);
    element_printf("vert(P+R) %B\n", x1);
    do_line(z1, P, R, Q);
    element_printf("line(P,R) %B\n", z1);
    element_div(x1, x1, z1);
    element_printf("x1 %B\n", x1);
    element_set(z, x1);

    for (;;) {
	printf("iteration %d: %d\n", m, mpz_tstbit(order,m));
	element_square(z, z);
	element_printf("squared: %B\n", z);
	do_tangent(z1, Z, Q);
	element_mul(z, z, z1);

	element_double(Z, Z);
	do_vert(z1, Z, Q);
	element_div(z, z, z1);
	element_printf("pre-if: %B\n", z);

	if (mpz_tstbit(order, m)) {
	    element_mul(z, z, x1);
	    do_vert(z1, P, Q);
	    element_mul(z, z, z1);
	    element_printf("done %B\n", z);
	    /*
	    do_line(z1, Z, P, Q);
	    element_mul(z, z, z1);
	    element_add(Z, Z, P);
	    do_vert(z1, Z, Q);
	    element_div(z, z, z1);
	    */
	}
	if (!m) break;
	m--;
    }

    element_clear(x1);
    element_clear(z1);
}
コード例 #4
0
ファイル: e_param.c プロジェクト: Russ36363/pbc-thesis
  void do_tangent(element_t e, element_t 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);
  }
コード例 #5
0
ファイル: curve.cpp プロジェクト: mahdiz/mpclib
static inline void double_no_check(point_ptr r, point_ptr p, element_ptr a) {
  element_t lambda, e0, e1;
  field_ptr f = r->x->field;

  element_init(lambda, f);
  element_init(e0, f);
  element_init(e1, f);

  //lambda = (3x^2 + a) / 2y
  element_square(lambda, p->x);
  element_mul_si(lambda, lambda, 3);
  element_add(lambda, lambda, a);

  element_double(e0, p->y);

  element_invert(e0, e0);
  element_mul(lambda, lambda, e0);
  //x1 = lambda^2 - 2x
  //element_add(e1, p->x, p->x);
  element_double(e1, p->x);
  element_square(e0, lambda);
  element_sub(e0, e0, e1);
  //y1 = (x - x1)lambda - y
  element_sub(e1, p->x, e0);
  element_mul(e1, e1, lambda);
  element_sub(e1, e1, p->y);

  element_set(r->x, e0);
  element_set(r->y, e1);
  r->inf_flag = 0;

  element_clear(lambda);
  element_clear(e0);
  element_clear(e1);
  return;
}
コード例 #6
0
ファイル: 59.c プロジェクト: Russ36363/pbc-thesis
static void do_tangent(element_ptr z, element_ptr V, element_ptr Q)
{
    element_ptr Vx = curve_x_coord(V);
    element_ptr Vy = curve_y_coord(V);
    element_ptr Qx = curve_x_coord(Q);
    element_ptr Qy = curve_y_coord(Q);

    element_t a, b, c;
    element_init_same_as(a, Vx);
    element_init_same_as(b, Vx);
    element_init_same_as(c, Vx);

    //a = -slope_tangent(V.x, V.y);
    //b = 1;
    //c = -(V.y + aV.x);
    /*
    //we could multiply by -2*V.y to avoid division so:
    //a = -(3 Vx^2 + cc->a)
    //b = 2 * Vy
    //c = -(2 Vy^2 + a Vx);
    //
    //actually no, since fasterweil won't work if we do this
    */
    element_square(a, Vx);
    //element_mul_si(a, a, 3);
    element_add(b, a, a);
    element_add(a, b, a);
    element_set1(b);
    element_add(a, a, b);
    element_neg(a, a);
    element_double(b, Vy);
    element_div(a, a, b);
    element_set1(b);
    element_mul(c, a, Vx);
    element_add(c, c, Vy);
    element_neg(c, c);

    element_printf("tan at %B: %B %B %B\n", V, a, b, c);

    element_mul(a, a, Qx);
    element_mul(b, b, Qy);
    element_add(c, c, a);
    element_add(z, c, b);
    element_printf("tan eval = %B\n", z);
    element_clear(a);
    element_clear(b);
    element_clear(c);
}
コード例 #7
0
ファイル: e_param.c プロジェクト: Russ36363/pbc-thesis
  void proj_double(void)
  {
    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);
  }
コード例 #8
0
ファイル: fieldquadratic.c プロジェクト: blynn/pbc
static void fq_square(element_ptr n, element_ptr a) {
  eptr p = a->data;
  eptr r = n->data;
  element_ptr nqr = fq_nqr(n->field);
  element_t e0, e1;

  element_init(e0, p->x->field);
  element_init(e1, e0->field);
  element_square(e0, p->x);
  element_square(e1, p->y);
  element_mul(e1, e1, nqr);
  element_add(e0, e0, e1);
  element_mul(e1, p->x, p->y);
  //TODO: which is faster?
  //element_add(e1, e1, e1);
  element_double(e1, e1);
  element_set(r->x, e0);
  element_set(r->y, e1);
  element_clear(e0);
  element_clear(e1);
}
コード例 #9
0
ファイル: 19.c プロジェクト: blynn/pbc
static void tate_18(element_ptr out, element_ptr P, element_ptr Q, element_ptr R, element_ptr S) {
  mpz_t pow;
  element_t PR;
  element_t QS;
  element_init(PR, P->field);
  element_init(QS, P->field);
  element_t outd;

  element_init(outd, out->field);

  mpz_init(pow);
  mpz_set_ui(pow, (19*19-1)/18);

  element_add(PR, P, R);
  element_add(QS, Q, S);

  if (element_is0(QS)) {
    element_t S2;
    element_init(S2, P->field);
    element_double(S2, S);
    miller(out, PR, S, S2, 18);
    miller(outd, R, S, S2, 18);
    element_clear(S2);
  } else {
    miller(out, PR, QS, S, 18);
    miller(outd, R, QS, S, 18);
  }

  element_clear(PR);
  element_clear(QS);

  element_invert(outd, outd);
  element_mul(out, out, outd);
  element_pow_mpz(out, out, pow);

  element_clear(outd);
  mpz_clear(pow);
}
コード例 #10
0
ファイル: window.cpp プロジェクト: pigeon119/LabProjects
void window(element_t ap,element_t p,int a,pairing_t pairing)
{
    static const int W = 1;
    static const int D = 1<<W;

    element_t dp[D];
    for(int i=0;i<D;i++)
        element_init_G1(dp[i],pairing);

    pre_process(dp,p,D);

    element_set0(ap);
    
    for(int i = 32/W-1;i>=0;i--)
    {
        int tmp = (a>>(i*W)) & ((1<<W)-1);

        for(int j=0;j<W;j++) element_double(ap,ap);
        if(tmp)
            element_add(ap,ap,dp[tmp]);
    }

}
コード例 #11
0
ファイル: d_param.c プロジェクト: blynn/pbc
// Requires cofactor is even. TODO: This seems to contradict a comment below.
// Requires in != out.
// Mangles in.
static void lucas_even(element_ptr out, element_ptr in, mpz_t cofactor) {
  if (element_is1(in)) {
    element_set(out, in);
    return;
  }
  element_t temp;
  element_init_same_as(temp, out);
  element_ptr in0 = element_x(in);
  element_ptr in1 = element_y(in);
  element_ptr v0 = element_x(out);
  element_ptr v1 = element_y(out);
  element_ptr t0 = element_x(temp);
  element_ptr t1 = element_y(temp);
  size_t j;

  element_set_si(t0, 2);
  element_double(t1, in0);

  element_set(v0, t0);
  element_set(v1, t1);

  j = mpz_sizeinbase(cofactor, 2) - 1;
  for (;;) {
    if (!j) {
      element_mul(v1, v0, v1);
      element_sub(v1, v1, t1);
      element_square(v0, v0);
      element_sub(v0, v0, t0);
      break;
    }
    if (mpz_tstbit(cofactor, j)) {
      element_mul(v0, v0, v1);
      element_sub(v0, v0, t1);
      element_square(v1, v1);
      element_sub(v1, v1, t0);
    } else {
      element_mul(v1, v0, v1);
      element_sub(v1, v1, t1);
      element_square(v0, v0);
      element_sub(v0, v0, t0);
    }
    j--;
  }

  // Assume cofactor = (q^2 - q + 1) / r is odd
  // thus v1 = V_k, v0 = V_{k-1}
  //   U = (P v1 - 2 v0) / (P^2 - 4)

  element_double(v0, v0);
  element_mul(in0, t1, v1);
  element_sub(in0, in0, v0);

  element_square(t1, t1);
  element_sub(t1, t1, t0);
  element_sub(t1, t1, t0);

  element_halve(v0, v1);
  element_div(v1, in0, t1);
  element_mul(v1, v1, in1);

  element_clear(temp);
}
コード例 #12
0
ファイル: singular.c プロジェクト: jun-kim/SEDA
//TODO: the following code is useless as the Tate pairing is degenerate on singular curves
static void sn_miller(element_t res, mpz_t q, element_t P,
    element_ptr Qx, element_ptr Qy) {
  //collate divisions
  int m;
  element_t v, vd;
  element_t Z;
  element_t a, b, c;
  element_t e0, e1;
  element_ptr Zx;
  element_ptr Zy;
  const element_ptr Px = curve_x_coord(P);
  const element_ptr Py = curve_y_coord(P);

  #define do_vertical(e)     \
    element_sub(e0, Qx, Zx); \
    element_mul(e, e, e0);

  //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 * (Zx + Zx + Zx + 2)
  //b = 2 * Zy
  //c = -(2 Zy^2 + a Zx);
  #define do_tangent(e)      \
    element_double(e0, Zx);  \
    element_add(a, Zx, e0);  \
    element_set_si(e0, 2);   \
    element_add(a, a, e0);   \
    element_mul(a, a, Zx);   \
    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, Qx);  \
    element_mul(e1, b, Qy);  \
    element_add(e0, e0, e1); \
    element_add(e0, e0, c);  \
    element_mul(e, e, e0);

  //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
  #define do_line(e)         \
    element_sub(b, Px, Zx);  \
    element_sub(a, Zy, Py);  \
    element_mul(e0, b, Zy);  \
    element_mul(c, a, Zx);   \
    element_add(c, c, e0);   \
    element_neg(c, c);       \
    element_mul(e0, a, Qx);  \
    element_mul(e1, b, Qy);  \
    element_add(e0, e0, e1); \
    element_add(e0, e0, c);  \
    element_mul(e, e, e0);

  element_init(a, Px->field);
  element_init(b, Px->field);
  element_init(c, Px->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);
  m = mpz_sizeinbase(q, 2) - 2;

  while(m >= 0) {
    element_mul(v, v, v);
    element_mul(vd, vd, vd);
    do_tangent(v);
    element_double(Z, Z);
    do_vertical(vd);
    if (mpz_tstbit(q, m)) {
      do_line(v);
      element_add(Z, Z, P);
      do_vertical(vd);
    }
    m--;
  }
  #undef do_tangent
  #undef do_vertical
  #undef do_line

  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);
}
コード例 #13
0
ファイル: fieldquadratic.c プロジェクト: blynn/pbc
static void fq_double(element_ptr n, element_ptr a) {
  eptr p = a->data;
  eptr r = n->data;
  element_double(r->x, p->x);
  element_double(r->y, p->y);
}
コード例 #14
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
}
コード例 #15
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);
}
コード例 #16
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
}
コード例 #17
0
ファイル: curve.cpp プロジェクト: mahdiz/mpclib
//compute c_i=a_i+a_i at one time.
static void multi_double(element_ptr c[], element_ptr a[], int n) {
  int i;
  element_t* table = (element_t*)pbc_malloc(sizeof(element_t)*n);  //a big problem?
  element_t e0, e1, e2;
  point_ptr q, r;
  curve_data_ptr cdp = (curve_data_ptr)a[0]->field->data;

  q = (point_ptr)a[0]->data;
  element_init(e0,q->y->field);
  element_init(e1,q->y->field);
  element_init(e2,q->y->field);

  for(i=0; i<n; i++){
	  q = (point_ptr)a[i]->data; r = (point_ptr)c[i]->data;
    element_init(table[i],q->y->field);

    if (q->inf_flag) {
      r->inf_flag = 1;
      continue;
    }
    if (element_is0(q->y)) {
      r->inf_flag = 1;
      continue;
    }
  }
  //to compute 1/2y multi. see Cohen's GTM139 Algorithm 10.3.4
  for(i=0; i<n; i++){
	  q = (point_ptr)a[i]->data;
    element_double(table[i],q->y);
    if(i>0) element_mul(table[i],table[i],table[i-1]);
  }
  element_invert(e2,table[n-1]); //ONLY ONE inv is required now.
  for(i=n-1; i>0; i--){
	  q = (point_ptr)a[i]->data;
    element_mul(table[i],table[i-1],e2);
    element_mul(e2,e2,q->y);
    element_double(e2,e2); //e2=e2*2y_j
  }
  element_set(table[0],e2); //e2 no longer used.

  for(i=0; i<n; i++){
	  q = (point_ptr)a[i]->data;
	  r = (point_ptr)c[i]->data;
    if(r->inf_flag) continue;

    //e2=lambda = (3x^2 + a) / 2y
    element_square(e2, q->x);
    element_mul_si(e2, e2, 3);
    element_add(e2, e2, cdp->a);

    element_mul(e2, e2, table[i]); //Recall that table[i]=1/2y_i
    //x1 = lambda^2 - 2x
    element_double(e1, q->x);
    element_square(e0, e2);
    element_sub(e0, e0, e1);
    //y1 = (x - x1)lambda - y
    element_sub(e1, q->x, e0);
    element_mul(e1, e1, e2);
    element_sub(e1, e1, q->y);
    element_set(r->x, e0);
    element_set(r->y, e1);
    r->inf_flag = 0;
  }

  element_clear(e0);
  element_clear(e1);
  element_clear(e2);
  for(i=0; i<n; i++){
    element_clear(table[i]);
  }
  pbc_free(table);
}
コード例 #18
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
}
コード例 #19
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;
}
コード例 #20
0
ファイル: f_param.c プロジェクト: blynn/pbc
static void cc_miller_no_denom(element_t res, mpz_t q, element_t P,
    element_ptr Qx, element_ptr Qy, element_t negalpha) {
  mp_bitcnt_t m;
  element_t v;
  element_t Z;
  element_t a, b, c;
  element_t t0;
  element_t e0, e1;
  element_ptr Zx, Zy;
  const element_ptr Px = curve_x_coord(P);
  const element_ptr Py = curve_y_coord(P);

  #define do_term(i, j, k, flag) {                                \
    element_ptr e2;                                               \
    e2 = element_item(e0, i);                                     \
    element_mul(e1, element_item(v, j), Qx);                      \
    if (flag == 1) element_mul(e1, e1, negalpha);                 \
    element_mul(element_x(e1), element_x(e1), a);                 \
    element_mul(element_y(e1), element_y(e1), a);                 \
    element_mul(e2, element_item(v, k), Qy);                      \
    element_mul(element_x(e2), element_x(e2), b);                 \
    element_mul(element_y(e2), element_y(e2), b);                 \
    element_add(e2, e2, e1);                                      \
    if (flag == 2) element_mul(e2, e2, negalpha);                 \
    element_mul(element_x(e1), element_x(element_item(v, i)), c); \
    element_mul(element_y(e1), element_y(element_item(v, i)), c); \
    element_add(e2, e2, e1);                                      \
  }

  // a, b, c lie in Fq
  // Qx, Qy lie in Fq^2
  // Qx is coefficient of x^4
  // Qy is coefficient of x^3
  //
  // computes v *= (a Qx x^4 + b Qy x^3 + c)
  //
  // recall x^6 = -alpha thus
  // x^4 (u0 + u1 x^1 + ... + u5 x^5) =
  // u0 x^4 + u1 x^5
  // - alpha u2 - alpha u3 x - alpha u4 x^2 - alpha u5 x^3
  // and
  // x^4 (u0 + u1 x^1 + ... + u5 x^5) =
  // u0 x^3 + u1 x^4 + u2 x^5
  // - alpha u3 - alpha u4 x - alpha u5 x^2
  #define f_miller_evalfn() { \
    do_term(0, 2, 3, 2);      \
    do_term(1, 3, 4, 2);      \
    do_term(2, 4, 5, 2);      \
    do_term(3, 5, 0, 1);      \
    do_term(4, 0, 1, 0);      \
    do_term(5, 1, 2, 0);      \
    element_set(v, e0);       \
  }
  /*
    element_ptr e1;

    e1 = element_item(e0, 4);

    element_mul(element_x(e1), element_x(Qx), a);
    element_mul(element_y(e1), element_y(Qx), a);

    e1 = element_item(e0, 3);

    element_mul(element_x(e1), element_x(Qy), b);
    element_mul(element_y(e1), element_y(Qy), b);

    element_set(element_x(element_item(e0, 0)), c);

    element_mul(v, v, e0);
   */

  //a = -3 Zx^2 since cc->a is 0 for D = 3
  //b = 2 * Zy
  //c = -(2 Zy^2 + a Zx);
  #define do_tangent() {     \
    element_square(a, Zx);   \
    element_mul_si(a, a, 3); \
    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);       \
                             \
    f_miller_evalfn();       \
  }

  //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
  #define do_line() {       \
    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);      \
                            \
    f_miller_evalfn();      \
  }

  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(e1, Qx->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);

  //TODO: sliding NAF
  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);
  element_clear(e1);
  #undef do_term
  #undef f_miller_evalfn
  #undef do_tangent
  #undef do_line
}
コード例 #21
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
}
コード例 #22
0
ファイル: 59.c プロジェクト: Russ36363/pbc-thesis
void shipseystange(element_t z, element_t P, element_t Q)
{
    mpz_t q1r;

    mpz_init(q1r);
    mpz_set_ui(q1r, 696);

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

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

    element_t v0m1, v0m2, v0m3;
    element_t v00, v01, v02, v03, v04;
    element_t v1m1, v10, v11;
    element_t t0, t1, t2;
    element_t W20inv;
    element_t Wm11inv;
    element_t W2m1inv;
    element_t sm2, sm1, s0, s1, s2, s3;
    element_t pm2, pm1, p0, p1, p2, p3;

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

    element_init_same_as(pm2, z);
    element_init_same_as(pm1, z);
    element_init_same_as(p0, z);
    element_init_same_as(p1, z);
    element_init_same_as(p2, z);
    element_init_same_as(p3, z);

    element_init_same_as(v0m3, z);
    element_init_same_as(v0m2, z);
    element_init_same_as(v0m1, z);
    element_init_same_as(v00, z);
    element_init_same_as(v01, z);
    element_init_same_as(v02, z);
    element_init_same_as(v03, z);
    element_init_same_as(v04, z);

    element_init_same_as(v1m1, z);
    element_init_same_as(v10, z);
    element_init_same_as(v11, z);

    element_init_same_as(W20inv, z);
    element_init_same_as(Wm11inv, z);
    element_init_same_as(W2m1inv, z);

    element_init_same_as(t0, z);
    element_init_same_as(t1, z);
    element_init_same_as(t2, z);

    element_set0(v0m1);
    element_set1(v00);
    element_neg(v0m2, v00);
    element_double(v01, y);

    element_neg(v0m3, v01);

    element_invert(W20inv, v01);

    element_sub(Wm11inv, x, x2);
    element_square(t1, Wm11inv);
    element_invert(Wm11inv, Wm11inv);
    element_double(t0, x);
    element_add(t0, t0, x2);
    element_mul(t1, t0, t1);
    element_add(t0, y, y2);
    element_square(t0, t0);
    element_sub(t0, t0, t1);
    element_invert(W2m1inv, t0);

    /* Let P=(x,y) since A=1, B=0 we have:
     * W(3,0) = 3x^4 + 6x^2 - 1
     * W(4,0) = 4y(x^6 + 5x^4 - 5x^2 - 1)
     */

    //t0 = x^2
    element_square(t0, x);

    //t1 = x^4
    element_square(t1, t0);

    //t2 = x^4 + 2 x^2
    element_double(t2, t0);
    element_add(t2, t2, t1);

    //v02 = W(3,0)
    element_double(v02, t2);
    element_add(v02, v02, t2);
    element_add(v02, v02, v0m2);

    //t2 = x^4 - x^2
    element_sub(t2, t1, t0);

    //v03 = 5(x^4 - x^2)
    element_double(v03, t2);
    element_double(v03, v03);
    element_add(v03, v03, t2);

    //t2 = x^6
    element_mul(t2, t0, t1);

    //v03 = W(4,0)
    element_add(v03, v03, t2);
    element_add(v03, v03, v0m2);
    element_double(v03, v03);
    element_double(v03, v03);
    element_mul(v03, v03, y);

    //v04 = W(5,0) = W(2,0)^3 W(4,0) - W(3,0)^3
    element_square(t0, v01);
    element_mul(t0, t0, v01);
    element_mul(v04, t0, v03);
    element_square(t0, v02);
    element_mul(t0, t0, v02);
    element_sub(v04, v04, t0);

    element_set1(v1m1);
    element_set1(v10);

    element_printf("x y: %B %B\n", x, y);
    element_printf("x2 y2: %B %B\n", x2, y2);
    element_sub(t0, x2, x);
    element_sub(t1, y2, y);
    element_div(t0, t1, t0);
    element_square(t0, t0);
    element_double(v11, x);
    element_add(v11, v11, x2);
    element_sub(v11, v11, t0);

    element_printf("VEC1: %B %B %B\n", v1m1, v10, v11);
    element_printf("VEC0: %B %B %B %B %B %B %B %B\n",
	    v0m3, v0m2, v0m1, v00, v01, v02, v03, v04);

    //Double
    element_square(sm2, v0m2);
    element_square(sm1, v0m1);
    element_square(s0, v00);
    element_square(s1, v01);
    element_square(s2, v02);
    element_square(s3, v03);

    element_mul(pm2, v0m3, v0m1);
    element_mul(pm1, v0m2, v00);
    element_mul(p0, v0m1, v01);
    element_mul(p1, v00, v02);
    element_mul(p2, v01, v03);
    element_mul(p3, v02, v04);

    element_mul(t0, pm1, sm2);
    element_mul(t1, pm2, sm1);
    element_sub(v0m3, t0, t1);

    element_mul(t1, pm2, s0);
    element_mul(t0, p0, sm2);
    element_sub(v0m2, t0, t1);
    element_mul(v0m2, v0m2, W20inv);

    element_mul(t0, p0, sm1);
    element_mul(t1, pm1, s0);
    element_sub(v0m1, t0, t1);

    element_mul(t1, pm1, s1);
    element_mul(t0, p1, sm1);
    element_sub(v00, t0, t1);
    element_mul(v00, v00, W20inv);

    element_mul(t0, p1, s0);
    element_mul(t1, p0, s1);
    element_sub(v01, t0, t1);

    element_mul(t1, p0, s2);
    element_mul(t0, p2, s0);
    element_sub(v02, t0, t1);
    element_mul(v02, v02, W20inv);

    element_mul(t0, p2, s1);
    element_mul(t1, p1, s2);
    element_sub(v03, t0, t1);

    element_mul(t1, p1, s3);
    element_mul(t0, p3, s1);
    element_sub(v04, t0, t1);
    element_mul(v04, v04, W20inv);

    element_square(t0, v10);
    element_mul(t1, v1m1, v11);

    element_mul(t2, pm1, t0);
    element_mul(v1m1, t1, sm1);
    element_sub(v1m1, v1m1, t2);

    element_mul(t2, p0, t0);
    element_mul(v10, t1, s0);
    element_sub(v10, v10, t2);

    element_mul(t2, p1, t0);
    element_mul(v11, t1, s1);
    element_sub(v11, v11, t2);
    element_mul(v11, v11, Wm11inv);

    element_printf("VEC1: %B %B %B\n", v1m1, v10, v11);
    element_printf("VEC0: %B %B %B %B %B %B %B %B\n",
	    v0m3, v0m2, v0m1, v00, v01, v02, v03, v04);

    //DoubleAdd
    element_square(sm2, v0m2);
    element_square(sm1, v0m1);
    element_square(s0, v00);
    element_square(s1, v01);
    element_square(s2, v02);
    element_square(s3, v03);

    element_mul(pm2, v0m3, v0m1);
    element_mul(pm1, v0m2, v00);
    element_mul(p0, v0m1, v01);
    element_mul(p1, v00, v02);
    element_mul(p2, v01, v03);
    element_mul(p3, v02, v04);

    element_mul(t1, pm2, s0);
    element_mul(t0, p0, sm2);
    element_sub(v0m3, t0, t1);
    element_mul(v0m3, v0m3, W20inv);

    element_mul(t0, p0, sm1);
    element_mul(t1, pm1, s0);
    element_sub(v0m2, t0, t1);

    element_mul(t1, pm1, s1);
    element_mul(t0, p1, sm1);
    element_sub(v0m1, t0, t1);
    element_mul(v0m1, v0m1, W20inv);

    element_mul(t0, p1, s0);
    element_mul(t1, p0, s1);
    element_sub(v00, t0, t1);

    element_mul(t1, p0, s2);
    element_mul(t0, p2, s0);
    element_sub(v01, t0, t1);
    element_mul(v01, v01, W20inv);

    element_mul(t0, p2, s1);
    element_mul(t1, p1, s2);
    element_sub(v02, t0, t1);

    element_mul(t1, p1, s3);
    element_mul(t0, p3, s1);
    element_sub(v03, t0, t1);
    element_mul(v03, v03, W20inv);

    element_mul(t0, p3, s2);
    element_mul(t1, p2, s3);
    element_sub(v04, t0, t1);

    element_square(t0, v10);
    element_mul(t1, v1m1, v11);

    element_mul(t2, p0, t0);
    element_mul(v1m1, t1, s0);
    element_sub(v1m1, v1m1, t2);

    element_mul(t2, p1, t0);
    element_mul(v10, t1, s1);
    element_sub(v10, v10, t2);
    element_mul(v10, v10, Wm11inv);

    element_mul(t2, t1, s2);
    element_mul(v11, p2, t0);
    element_sub(v11, v11, t2);
    element_mul(v11, v11, W2m1inv);

    element_printf("VEC1: %B %B %B\n", v1m1, v10, v11);
    element_printf("VEC0: %B %B %B %B %B %B %B %B\n",
	    v0m3, v0m2, v0m1, v00, v01, v02, v03, v04);
    element_div(z, v11, v01);
    element_printf("prepow: %B\n", z);

    element_pow_mpz(z, z, q1r);

    mpz_clear(q1r);
}