Пример #1
0
/* computing of $(-t^2 +u*s -t*p -p^2)^3$
 * The algorithm is by J.Beuchat et.al, in the paper of "Algorithms and Arithmetic Operators for Computing
 * the $eta_T$ Pairing in Characteristic Three", algorithm 4 in the appendix */
static void algorithm4a(element_t S, element_t t, element_t u) {
    field_ptr f = FIELD(t);
    element_t e1, c0, c1, m0, v0, v2;
    element_init(e1, f);
    element_init(c0, f);
    element_init(c1, f);
    element_init(m0, f);
    element_init(v0, f);
    element_init(v2, f);
    element_set1(e1);
    element_cubic(c0, t); // c0 == t^3
    element_cubic(c1, u);
    element_neg(c1, c1); // c1 == -u^3
    element_mul(m0, c0, c0); // m0 == c0^2
    element_neg(v0, m0); // v0 == -c0^2
    element_sub(v0, v0, c0); // v0 == -c0^2 -c0
    element_sub(v0, v0, e1); // v0 == -c0^2 -c0 -1
    element_set1(v2);
    element_sub(v2, v2, c0); // v2 == 1 -c0
    // v1 == c1
    // S == [[v0, v1], [v2, f3m.zero()], [f3m.two(), f3m.zero()]]
    element_set(ITEM(S,0,0), v0);
    element_set(ITEM(S,0,1), c1);
    element_set(ITEM(S,1,0), v2);
    element_set0(ITEM(S,1,1));
    element_neg(ITEM(S,2,0), e1);
    element_set0(ITEM(S,2,1));
    element_clear(e1);
    element_clear(c0);
    element_clear(c1);
    element_clear(m0);
    element_clear(v0);
    element_clear(v2);
}
Пример #2
0
/* computing $c <- U^M, M=(3^{3m}-1)*(3^m+1)*(3^m+1-\mu*b*3^{(m+1)//2})$
 * This is the algorithm 8 in the paper above. */
static void algorithm8(element_t c, element_t u) {
    field_ptr f6 = FIELD(u), f = FIELD(ITEM(u,0,0));
    params *p = (params *) f->data;
    element_t v, w;
    element_init(v, f6);
    element_init(w, f6);
    algorithm6(v, u);
    algorithm7(v, v);
    element_set(w, v);
    int i;
    for (i = 0; i < (p->m + 1) / 2; i++)
        element_cubic(w, w);
    algorithm7(v, v);
    if (p->m % 12 == 1 || p->m % 12 == 11) { // w <= w^{-\mu*b}
        element_ptr e;
        e = ITEM(w,0,1);
        element_neg(e, e);
        e = ITEM(w,1,1);
        element_neg(e, e);
        e = ITEM(w,2,1);
        element_neg(e, e);
    }
    element_mul(c, v, w);
    element_clear(v);
    element_clear(w);
}
Пример #3
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++;
  }
Пример #4
0
static void point_add(element_t c, element_t a, element_t b) {
    point_ptr p1 = DATA(a), p2 = DATA(b), p3 = DATA(c);
    int inf1 = p1->isinf, inf2 = p2->isinf;
    element_ptr x1 = p1->x, y1 = p1->y, x2 = p2->x, y2 = p2->y;
    field_ptr f = FIELD(x1);
    if (inf1) {
        point_set(c, b);
        return;
    }
    if (inf2) {
        point_set(c, a);
        return;
    }
    element_t v0, v1, v2, v3, v4, ny2;
    element_init(v0, f);
    element_init(v1, f);
    element_init(v2, f);
    element_init(v3, f);
    element_init(v4, f);
    element_init(ny2, f);
    if (!element_cmp(x1, x2)) { // x1 == x2
        element_neg(ny2, y2); // ny2 == -y2
        if (!element_cmp(y1, ny2)) {
            p3->isinf = 1;
            goto end;
        }
        if (!element_cmp(y1, y2)) { // y1 == y2
            element_invert(v0, y1); // v0 == y1^{-1}
            element_mul(v1, v0, v0); // v1 == [y1^{-1}]^2
            element_add(p3->x, v1, x1); // v1 == [y1^{-1}]^2 + x1
            element_cubic(v2, v0); // v2 == [y1^{-1}]^3
            element_add(v2, v2, y1); // v2 == [y1^{-1}]^3 + y1
            element_neg(p3->y, v2); // p3 == -([y1^{-1}]^3 + y1)
            p3->isinf = 0;
            goto end;
        }
    }
    // $P1 \ne \pm P2$
    element_sub(v0, x2, x1); // v0 == x2-x1
    element_invert(v1, v0); // v1 == (x2-x1)^{-1}
    element_sub(v0, y2, y1); // v0 == y2-y1
    element_mul(v2, v0, v1); // v2 == (y2-y1)/(x2-x1)
    element_mul(v3, v2, v2); // v3 == [(y2-y1)/(x2-x1)]^2
    element_cubic(v4, v2); // v4 == [(y2-y1)/(x2-x1)]^3
    element_add(v0, x1, x2); // v0 == x1+x2
    element_sub(v3, v3, v0); // v3 == [(y2-y1)/(x2-x1)]^2 - (x1+x2)
    element_add(v0, y1, y2); // v0 == y1+y2
    element_sub(v4, v0, v4); // v4 == (y1+y2) - [(y2-y1)/(x2-x1)]^3
    p3->isinf = 0;
    element_set(p3->x, v3);
    element_set(p3->y, v4);
end:
    element_clear(v0);
    element_clear(v1);
    element_clear(v2);
    element_clear(v3);
    element_clear(v4);
    element_clear(ny2);
}
Пример #5
0
// Requires e to be a point on an elliptic curve.
int element_from_bytes_compressed(element_ptr e, unsigned char *data) {
	curve_data_ptr cdp = (curve_data_ptr)e->field->data;
  point_ptr P = (point_ptr)e->data;
  int len;
  len = element_from_bytes(P->x, data);
  point_from_x(P, P->x, cdp->a, cdp->b);

  if (data[len]) {
    if (element_sign(P->y) < 0) element_neg(P->y, P->y);
  } else if (element_sign(P->y) > 0) {
    element_neg(P->y, P->y);
  }
  len++;
  return len;
}
Пример #6
0
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
static void do_vert(element_ptr z, element_ptr V, element_ptr Q)
{
    element_ptr Vx = curve_x_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 = 1
    //b = 0;
    //c = -Vx
    element_set1(a);
    element_set0(b);
    element_neg(c, Vx);

    element_printf("vert at %B: %B %B %B\n", Vx, 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("vert eval = %B\n", z);
    element_clear(a);
    element_clear(b);
    element_clear(c);
}
Пример #8
0
// The final powering, where we standardize the coset representative.
static void cc_tatepower(element_ptr out, element_ptr in, pairing_t pairing) {
  pptr p = pairing->data;
  #define qpower(sign) {                         \
    polymod_const_mul(e2, inre[1], p->xpowq);    \
    element_set(e0re, e2);                       \
    polymod_const_mul(e2, inre[2], p->xpowq2);   \
    element_add(e0re, e0re, e2);                 \
    element_add(e0re0, e0re0, inre[0]);          \
                                                 \
    if (sign > 0) {                              \
      polymod_const_mul(e2, inim[1], p->xpowq);  \
      element_set(e0im, e2);                     \
      polymod_const_mul(e2, inim[2], p->xpowq2); \
      element_add(e0im, e0im, e2);               \
      element_add(e0im0, e0im0, inim[0]);        \
    } else {                                     \
      polymod_const_mul(e2, inim[1], p->xpowq);  \
      element_neg(e0im, e2);                     \
      polymod_const_mul(e2, inim[2], p->xpowq2); \
      element_sub(e0im, e0im, e2);               \
      element_sub(e0im0, e0im0, inim[0]);        \
    }                                            \
  }
  if (p->k == 6) {
    // See thesis, section 6.9, "The Final Powering", which gives a formula
    // for the first step of the final powering when Fq6 has been implemented
    // as a quadratic extension on top of a cubic extension.
    element_t e0, e2, e3;
    element_init(e0, p->Fqk);
    element_init(e2, p->Fqd);
    element_init(e3, p->Fqk);
    element_ptr e0re = element_x(e0);
    element_ptr e0im = element_y(e0);
    element_ptr e0re0 = ((element_t *) e0re->data)[0];
    element_ptr e0im0 = ((element_t *) e0im->data)[0];
    element_t *inre = element_x(in)->data;
    element_t *inim = element_y(in)->data;
    // Expressions in the formula are similar, hence the following function.
    qpower(1);
    element_set(e3, e0);
    element_set(e0re, element_x(in));
    element_neg(e0im, element_y(in));
    element_mul(e3, e3, e0);
    qpower(-1);
    element_mul(e0, e0, in);
    element_invert(e0, e0);
    element_mul(in, e3, e0);

    element_set(e0, in);
    // We use Lucas sequences to complete the final powering.
    lucas_even(out, e0, pairing->phikonr);

    element_clear(e0);
    element_clear(e2);
    element_clear(e3);
  } else {
    element_pow_mpz(out, in, p->tateexp);
  }
  #undef qpower
}
Пример #9
0
static void curve_from_hash(element_t a, void *data, int len) {
  element_t t, t1;
  point_ptr p = (point_ptr)a->data;
  curve_data_ptr cdp = (curve_data_ptr)a->field->data;

  element_init(t, cdp->field);
  element_init(t1, cdp->field);
  p->inf_flag = 0;
  element_from_hash(p->x, data, len);
  for(;;) {
    element_square(t, p->x);
    element_add(t, t, cdp->a);
    element_mul(t, t, p->x);
    element_add(t, t, cdp->b);
    if (element_is_sqr(t)) break;
    // Compute x <- x^2 + 1 and try again.
    element_square(p->x, p->x);
    element_set1(t);
    element_add(p->x, p->x, t);
  }
  element_sqrt(p->y, t);
  if (element_sgn(p->y) < 0) element_neg(p->y, p->y);

  if (cdp->cofac) element_mul_mpz(a, a, cdp->cofac);

  element_clear(t);
  element_clear(t1);
}
Пример #10
0
static void point_invert(element_ptr e, element_ptr a) {
    point_ptr r = DATA(e), p = DATA(a);
    r->isinf = p->isinf;
    if (!p->isinf) {
        element_set(r->x, p->x);
        element_neg(r->y, p->y);
    }
}
Пример #11
0
static void sn_invert(element_ptr c, element_ptr a) {
  point_ptr r = c->data, p = a->data;

  if (p->inf_flag) {
    r->inf_flag = 1;
    return;
  }
  r->inf_flag = 0;
  element_set(r->x, p->x);
  element_neg(r->y, p->y);
}
Пример #12
0
static void do_line(element_ptr z, element_ptr V, element_ptr P, element_ptr Q)
{
    element_ptr Vx = curve_x_coord(V);
    element_ptr Vy = curve_y_coord(V);
    element_ptr Px = curve_x_coord(P);
    element_ptr Py = curve_y_coord(P);
    element_ptr Qx = curve_x_coord(Q);
    element_ptr Qy = curve_y_coord(Q);

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

    //a = -(B.y - A.y) / (B.x - A.x);
    //b = 1;
    //c = -(A.y + a * A.x);

    element_sub(a, Py, Vy);
    element_sub(b, Vx, Px);
    element_div(a, a, b);
    element_set1(b);
    element_mul(c, a, Vx);
    element_add(c, c, Vy);
    element_neg(c, c);

    /*
    //but we could multiply by B.x - A.x to avoid division, so
    //a = -(By - Ay)
    //b = Bx - Ax
    //c = -(Ay b + a Ax);
    element_sub(a, Vy, Py);
    element_sub(b, Px, Vx);
    element_mul(c, Vx, Py);
    element_mul(e0, Vy, Px);
    element_sub(c, c, e0);
    //
    //actually no, since fasterweil won't work if we do this
    */

    element_printf("line 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(" = %B\n", z);

    element_clear(a);
    element_clear(b);
    element_clear(c);
    element_clear(e0);
}
Пример #13
0
void weil(element_t w, element_t g, element_t h)
{
    element_t gr;
    element_t hs;
    element_t r;
    element_t s;
    element_t z, z0, z1;

    element_init(z, Fq2);
    element_init(z0, Fq2);
    element_init(z1, Fq2);

    element_init_same_as(gr, g);
    element_init_same_as(hs, h);
    element_init_same_as(r, g);
    element_init_same_as(s, h);

    element_random(r);
    element_random(s);
    //point_random always takes the same square root
    //why not take the other one for once?
    element_neg(r, r);
    element_set_str(r, "[[40,0],[54,0]]", 0);
    element_set_str(s, "[[48,55],[28,51]]", 0);

    element_printf("chose R = %B\n", r);
    element_printf("chose S = %B\n", s);
    element_add(gr, g, r);
    element_add(hs, h, s);

    element_printf("P+R = %B\n", gr);
    element_printf("Q+S = %B\n", hs);
    miller(z, gr, r, g, hs);
    miller(z0, gr, r, g, s);
    element_div(z1, z, z0);
    element_printf("num: %B\n", z1);

    miller(z, hs, s, h, gr);
    miller(z0, hs, s, h, r);
    element_div(w, z, z0);
    element_printf("denom: %B\n", w);

    element_div(w, z1, w);

    element_clear(gr);
    element_clear(r);
    element_clear(hs);
    element_clear(s);
    element_clear(z);
    element_clear(z0);
    element_clear(z1);
}
Пример #14
0
  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);
  }
Пример #15
0
/* $e <- a^3$ */
static void gf32m_cubic(element_t e, element_t a) {
    element_ptr a0 = GF32M(a)->_0, a1 = GF32M(a)->_1, e0 = GF32M(e)->_0, e1 =
            GF32M(e)->_1;
    field_ptr base = BASE(a);
    element_t c0, c1;
    element_init(c0, base);
    element_init(c1, base);
    element_cubic(c0, a0);
    element_cubic(c1, a1);
    element_neg(c1, c1); // c1 == -(a1^3)
    element_set(e0, c0);
    element_set(e1, c1);
    element_clear(c0);
    element_clear(c1);
}
Пример #16
0
  void do_line(void) {
    // 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); add1++;
    element_sub(a, Zy, Py); 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++;
  }
Пример #17
0
static void fi_invert(element_ptr n, element_ptr a) {
  eptr p = a->data;
  eptr r = n->data;
  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_add(e0, e0, e1);
  element_invert(e0, e0);
  element_mul(r->x, p->x, e0);
  element_neg(e0, e0);
  element_mul(r->y, p->y, e0);

  element_clear(e0);
  element_clear(e1);
}
Пример #18
0
static void test_gf3m_sqrt(void) {
    mpz_t t;
    mpz_init(t);
    mpz_sub_ui(t, a->field->order, 1); // t == field_order - 1
    element_random(a);
    element_pow_mpz(a, a, t);
    EXPECT(!element_cmp(a, e1));

    while(1){
        element_random(a);
        element_mul(b, a, a);
        element_sqrt(b, b);
        if(element_cmp(a, b)) {// a != b
            element_neg(b, b);
            if(!element_cmp(a, b)) break;
        }
    }
    mpz_clear(t);
}
Пример #19
0
// USER JOIN PHASE 5 - user key generation (Join)
int xsgs_user_join_phase5(XSGS_PUBLIC_KEY* gpk, XSGS_USER_CERT* ucert,
		XSGS_USER_KEY* uk, XSGS_JOIN_PHASE4* jpd4) {
	int ret;
	pairing_ptr pairing = gpk->pairing;
	field_ptr Fp = pairing->Zr;
	element_t gt1, gt2, y_neg, g1;

	element_init(ucert->x, Fp);
	element_set(ucert->x, jpd4->x);

	// check A^(x + gamma) = G1 * H^y
	// i.e.: e(A, G2)^x * e(A, W) * e(H, G2)^-y == e(G1, G2)
	element_init(y_neg, Fp);
	element_init_G1(g1, pairing);
	element_init_GT(gt1, pairing);
	element_init_GT(gt2, pairing);

	// gt1 = e(A, G2)^x * e(A, W) * e(H, G2)^-y
	//     = e(A^x * H^-y, G2) * e(A, W)
	element_neg(y_neg, uk->y);
	element_pow_naf2(g1, ucert->A, ucert->x, gpk->H, y_neg);
	element_pairing(gt1, g1, gpk->G2);
	element_pairing(gt2, ucert->A, gpk->W);
	element_mul(gt1, gt1, gt2);

	// gt2 = e(G1, G2)
	element_pairing(gt2, gpk->G1, gpk->G2);

	// check gt1 == gt2
	ret = element_cmp(gt1, gt2);

	element_clear(g1);
	element_clear(y_neg);
	element_clear(gt1);
	element_clear(gt2);

	return ret;
}
Пример #20
0
void setup(void) {
    field_init_gf3m(f97, 97, 12);
    element_init(a, f97);
    element_init(b, f97);
    element_init(e0, f97);
    element_init(e1, f97);
    element_init(e2, f97);
    element_set1(e1);
    element_neg(e2, e1);

    field_init_gf32m(f97_2, f97);
    element_init(a2, f97_2);
    element_init(b2, f97_2);

    field_init_gf33m(f97_3, f97);
    element_init(a3, f97_3);
    element_init(b3, f97_3);

    field_init_gf33m(f97_6, f97_2);
    element_init(a6, f97_6);
    element_init(b6, f97_6);

    data = pbc_malloc(f97->fixed_length_in_bytes);
}
Пример #21
0
// USER JOIN PHASE 3 - user key generation (Join)
int xsgs_user_join_phase3(XSGS_PUBLIC_KEY* gpk, XSGS_USER_CERT* ucert,
		XSGS_JOIN_PHASE1* jpd1, XSGS_JOIN_PHASE2* jpd2, XSGS_JOIN_PHASE3* jpd3,
		char* usk_pem_filename) {
	int ret;
	pairing_ptr pairing = gpk->pairing;
	field_ptr Fp = pairing->Zr;
	element_t B, D, R1, R2, h, g1, gt;

	// B = e(G1 * C, G2) / e(A, W) = e(G1 * C, G2) * e(A^-1, W)
	element_init_GT(B, pairing);
	element_init_G1(g1, pairing);
	element_init_GT(gt, pairing);

	element_mul(g1, gpk->G1, jpd1->C);
	element_pairing(B, g1, gpk->G2);
	element_invert(g1, jpd2->A);
	element_pairing(gt, g1, gpk->W);
	element_mul(B, B, gt);

	// D = e(A, G2)
	element_init_GT(D, pairing);
	element_pairing(D, jpd2->A, gpk->G2);

	// verifies A e Group1, Checks V
	element_init(h, Fp);
	element_from_hash(h, jpd1->U.hash, JOIN_HASH_BITS / 8);
	element_neg(h, h);

	// R1 = B^s * T1^h
	element_init_GT(R1, pairing);
	element_pow_naf2(R1, B, jpd2->V.s, jpd2->V.T1, h);

	// R2 = D^s * T2^h
	element_init_GT(R2, pairing);
	element_pow_naf2(R2, D, jpd2->V.s, jpd2->V.T2, h);

	// clear tmp
	element_clear(g1);
	element_clear(gt);
	element_clear(h);

	// h = H(B, D, T1, T2, R1, R2)
	DWORD data_len = element_length_in_bytes(B) + element_length_in_bytes(D)
			+ element_length_in_bytes(jpd2->V.T1)
			+ element_length_in_bytes(jpd2->V.T2) + element_length_in_bytes(R1)
			+ element_length_in_bytes(R2);

	BYTE* data_buf = (BYTE*) malloc(data_len);
	data_buf += element_to_bytes(data_buf, B);
	data_buf += element_to_bytes(data_buf, D);
	data_buf += element_to_bytes(data_buf, jpd2->V.T1);
	data_buf += element_to_bytes(data_buf, jpd2->V.T2);
	data_buf += element_to_bytes(data_buf, R1);
	data_buf += element_to_bytes(data_buf, R2);
	data_buf -= data_len;

	BYTE* hash = (BYTE*) malloc(JOIN_HASH_BITS / 8);
	xsgs_hash(data_buf, data_len * 8, hash, JOIN_HASH_BITS);

	free(data_buf);
	element_clear(B);
	element_clear(D);
	element_clear(R1);
	element_clear(R2);

	// compare hashes
	ret = memcmp(jpd2->V.hash, hash, JOIN_HASH_BITS / 8);
	free(hash);
	if (!ret) {
		element_init_G1(ucert->A, pairing);
		element_set(ucert->A, jpd2->A);

		// S = sign(A)
		DWORD msg_len = element_length_in_bytes(ucert->A);
		BYTE* msg = (BYTE*) malloc(msg_len);
		element_to_bytes(msg, ucert->A);
		ret = xsgs_rsa_sign(usk_pem_filename, msg, msg_len, &(jpd3->S.sig), &(jpd3->S.len));
		free(msg);
	}

	// return ( S = (rsa signature length, rsa signature) )
	return ret;
}
Пример #22
0
void pbc_param_init_f_gen(pbc_param_t p, int bits) {
  f_init(p);
  f_param_ptr fp = p->data;
  //36 is a 6-bit number
  int xbit = (bits - 6) / 4;
  //TODO: use binary search to find smallest appropriate x
  mpz_t x, t;
  mpz_ptr q = fp->q;
  mpz_ptr r = fp->r;
  mpz_ptr b = fp->b;
  field_t Fq, Fq2, Fq2x;
  element_t e1;
  element_t f;
  field_t c;
  element_t P;

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

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

    mpz_add_ui(x, x, 1);
  }

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

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

    element_random(P);

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

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

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

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

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

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

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

  element_clear(f);

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

  mpz_clear(t);
  mpz_clear(x);
}
Пример #23
0
static void fq_neg(element_ptr n, element_ptr a) {
  eptr p = a->data;
  eptr r = n->data;
  element_neg(r->x, p->x);
  element_neg(r->y, p->y);
}
Пример #24
0
/* $c <- (-a)$ */
static void gf32m_neg(element_t c, element_t a) {
    element_ptr a0 = GF32M(a)->_0, a1 = GF32M(a)->_1, c0 = GF32M(c)->_0, c1 =
            GF32M(c)->_1;
    element_neg(c0, a0);
    element_neg(c1, a1);
}
Пример #25
0
static val_ptr run_neg(val_ptr v[]) {
	element_neg(v[0]->elem, v[0]->elem);
	return v[0];
}
Пример #26
0
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
}
Пример #27
0
// 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);
}
Пример #28
0
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
}
Пример #29
0
static void test_gf3m_neg(void) {
    element_random(a);
    element_neg(b, a);
    element_add(b, a, b);
    EXPECT(!element_cmp(b, e0));
}
Пример #30
0
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);
}