Beispiel #1
0
/* computation of $c <- U ^ {3^m+1}$, $U \in T_2(F_{3^3M})$
 * This is the algorithm 7 in the paper above. */
static void algorithm7(element_t c, element_t u) {
    element_ptr u0 = ITEM(u,0,0), u1 = ITEM(u,0,1), u2 = ITEM(u,1,0), u3 =
                                           ITEM(u,1,1), u4 = ITEM(u,2,0), u5 = ITEM(u,2,1);
    field_ptr f = FIELD(u0); /*GF(3^m)*/
    params *p = PARAM(u0);
    element_t a0, a1, a2, a3, a4, a5, a6, m0, m1, m2, m3, m4, m5, m6, m7, m8,
              v0, v1, v2, v3, v4, v5, e1;
    element_init(a0, f);
    element_init(a1, f);
    element_init(a2, f);
    element_init(a3, f);
    element_init(a4, f);
    element_init(a5, f);
    element_init(a6, f);
    element_init(m0, f);
    element_init(m1, f);
    element_init(m2, f);
    element_init(m3, f);
    element_init(m4, f);
    element_init(m5, f);
    element_init(m6, f);
    element_init(m7, f);
    element_init(m8, f);
    element_init(v0, f);
    element_init(v1, f);
    element_init(v2, f);
    element_init(v3, f);
    element_init(v4, f);
    element_init(v5, f);
    element_init(e1, f);
    element_set1(e1);
    element_add(a0, u0, u1);
    element_add(a1, u2, u3);
    element_sub(a2, u4, u5);
    element_mul(m0, u0, u4);
    element_mul(m1, u1, u5);
    element_mul(m2, u2, u4);
    element_mul(m3, u3, u5);
    element_mul(m4, a0, a2);
    element_mul(m5, u1, u2);
    element_mul(m6, u0, u3);
    element_mul(m7, a0, a1);
    element_mul(m8, a1, a2);
    element_add(a3, m5, m6);
    element_sub(a3, a3, m7);
    element_neg(a4, m2);
    element_sub(a4, a4, m3);
    element_sub(a5, m3, m2);
    element_sub(a6, m1, m0);
    element_add(a6, a6, m4);
    if (p->m % 6 == 1) {
        element_add(v0, m0, m1);
        element_add(v0, v0, a4);
        element_add(v0, e1, v0);
        element_sub(v1, m5, m6);
        element_add(v1, v1, a6);
        element_sub(v2, a4, a3);
        element_add(v3, m8, a5);
        element_sub(v3, v3, a6);
        element_add(v4, a3, a4);
        element_neg(v4, v4);
        element_add(v5, m8, a5);
    } else { // p->m % 6 == 5
        element_add(v0, m0, m1);
        element_sub(v0, v0, a4);
        element_add(v0, e1, v0);
        element_sub(v1, m6, m5);
        element_add(v1, v1, a6);
        element_set(v2, a3);
        element_add(v3, m8, a5);
        element_add(v3, v3, a6);
        element_add(v4, a3, a4);
        element_neg(v4, v4);
        element_add(v5, m8, a5);
        element_neg(v5, v5);
    }
    element_set(ITEM(c,0,0), v0);
    element_set(ITEM(c,0,1), v1);
    element_set(ITEM(c,1,0), v2);
    element_set(ITEM(c,1,1), v3);
    element_set(ITEM(c,2,0), v4);
    element_set(ITEM(c,2,1), v5);
    element_clear(a0);
    element_clear(a1);
    element_clear(a2);
    element_clear(a3);
    element_clear(a4);
    element_clear(a5);
    element_clear(a6);
    element_clear(m0);
    element_clear(m1);
    element_clear(m2);
    element_clear(m3);
    element_clear(m4);
    element_clear(m5);
    element_clear(m6);
    element_clear(m7);
    element_clear(m8);
    element_clear(v0);
    element_clear(v1);
    element_clear(v2);
    element_clear(v3);
    element_clear(v4);
    element_clear(v5);
    element_clear(e1);
}
/* $c <- a-b$ */
static void gf32m_sub(element_t c, element_t a, element_t b) {
    element_ptr a0 = GF32M(a)->_0, a1 = GF32M(a)->_1, b0 = GF32M(b)->_0, b1 =
            GF32M(b)->_1, c0 = GF32M(c)->_0, c1 = GF32M(c)->_1;
    element_sub(c0, a0, b0);
    element_sub(c1, a1, b1);
}
Beispiel #3
0
/* this is the algorithm 4 in the paper of J.Beuchat et.al, "Algorithms and Arithmetic Operators for Computing
 * the $eta_T$ Pairing in Characteristic Three" */
static void algorithm4(element_t c, element_ptr xp, element_ptr yp,
                       element_ptr xq, element_ptr yq) {
    params *p = PARAM(xp);
    unsigned int re = p->m % 12;
    field_ptr f = FIELD(xp) /*GF(3^m)*/, f6 = FIELD(c) /*GF(3^{6*m})*/;
    element_t e1, xpp, ypp, xqq, yqq, t, nt, nt2, v1, v2, a1, a2, R, u, S;
    element_init(e1, f);
    element_init(xpp, f);
    element_init(ypp, f);
    element_init(xqq, f);
    element_init(yqq, f);
    element_init(t, f);
    element_init(nt, f);
    element_init(nt2, f);
    element_init(v1, f);
    element_init(v2, f);
    element_init(a1, f6);
    element_init(a2, f6);
    element_init(R, f6);
    element_init(u, f);
    element_init(S, f6);
    element_set1(e1);
    element_set(xpp, xp);
    xp = xpp; // clone
    element_add(xp, xp, e1); // xp == xp + b
    element_set(ypp, yp);
    yp = ypp; // clone
    if (re == 1 || re == 11)
        element_neg(yp, yp); // yp == -\mu*b*yp, \mu == 1 when re==1, or 11
    element_set(xqq, xq);
    xq = xqq; // clone
    element_cubic(xq, xq); // xq == xq^3
    element_set(yqq, yq);
    yq = yqq; // clone
    element_cubic(yq, yq); // yq == yq^3
    element_add(t, xp, xq); // t == xp+xq
    element_neg(nt, t); // nt == -t
    element_mul(nt2, t, nt); // nt2 == -t^2
    element_mul(v2, yp, yq); // v2 == yp*yq
    element_mul(v1, yp, t); // v1 == yp*t
    if (re == 7 || re == 11) { // \lambda == 1
        element_t nyp, nyq;
        element_init(nyp, f);
        element_init(nyq, f);
        element_neg(nyp, yp); // nyp == -yp
        element_neg(nyq, yq); // nyq == -yq
        element_set(ITEM(a1,0,0), v1);
        element_set(ITEM(a1,0,1), nyq);
        element_set(ITEM(a1,1,0), nyp);
        element_clear(nyp);
        element_clear(nyq);
    } else { // \lambda == -1
        element_neg(v1, v1); // v1 == -yp*t
        element_set(ITEM(a1,0,0), v1);
        element_set(ITEM(a1,0,1), yq);
        element_set(ITEM(a1,1,0), yp);
    }
    // a2 == -t^2 +yp*yq*s -t*p -p^2
    element_set(ITEM(a2,0,0), nt2);
    element_set(ITEM(a2,0,1), v2);
    element_set(ITEM(a2,1,0), nt);
    element_neg(ITEM(a2,2,0), e1);
    element_mul(R, a1, a2);
    int i;
    for (i = 0; i < (p->m - 1) / 2; i++) {
        element_cubic(R, R);
        element_cubic(xq, xq);
        element_cubic(xq, xq);
        element_sub(xq, xq, e1); // xq <= xq^9-b
        element_cubic(yq, yq);
        element_cubic(yq, yq);
        element_neg(yq, yq); // yq <= -yq^9
        element_add(t, xp, xq); // t == xp+xq
        element_neg(nt, t); // nt == -t
        element_mul(nt2, t, nt); // nt2 == -t^2
        element_mul(u, yp, yq); // u == yp*yq
        element_set0(S);
        element_set(ITEM(S,0,0), nt2);
        element_set(ITEM(S,0,1), u);
        element_set(ITEM(S,1,0), nt);
        element_neg(ITEM(S,2,0), e1);
        element_mul(R, R, S);
    }
    element_set(c, R);
    element_clear(e1);
    element_clear(xpp);
    element_clear(ypp);
    element_clear(xqq);
    element_clear(yqq);
    element_clear(t);
    element_clear(nt);
    element_clear(nt2);
    element_clear(v1);
    element_clear(v2);
    element_clear(a1);
    element_clear(a2);
    element_clear(R);
    element_clear(u);
    element_clear(S);
}
Beispiel #4
0
//============================================
//   四則演算のテストプログラム
//============================================
void test_arithmetic_operation(Field f)
{
    int i;
    unsigned long long int t1, t2;
    Element a, b, c, d;

    char loop[] = "100";

    mpz_t e, exp;

    //--------------------
    //  init
    //--------------------
    element_init(a, f);
    element_init(b, f);
    element_init(c, f);
    element_init(d, f);

    //--------------------
    //  add
    //--------------------
    element_set_str(a, "1C12C39A2AD14054EDC9EE504301127AFFEEAADC59A78B50FCFFED87AC6EB8BF 20E1A922384561EA82602CD664D85D442DAC5D391E142ABB3CFEC2A095C22DF9");
    element_set_str(b, "F1B91250A124F268B8239185B23B31EB25179A11A9A0398E61B701F7D4F7265 20D206C5F7D007EDBA34A4B041622289D64F04CA28CEAC490619585AA14F7B2F");
    element_set_str(d, "7BD59BA97A27FBD2AD60CD0173FC358353DE53D5C418EE8649AFDA729BE2B23 1E42B4E392D45A19EE1EB6EE1F557D8C86F922C32EE2D702C497BAFB3711A927");

    element_add(c, a, b);

    assert(element_cmp(c, d) == 0);

    t1 = rdtsc();
    for (i = 0; i < N; i++) { element_add(c, a, b); }
    t2 = rdtsc();

    printf("element add: %.2lf [clock]\n", (double)(t2 - t1) / N);

    //--------------------
    //  sub
    //--------------------
    element_set(d, c);
    element_sub(c, c, d);

    assert(element_is_zero(c));

    //--------------------
    //  mul
    //--------------------
    element_mul(c, a, b);
    element_set_str(d, "1D0562FF0AB317FFDE555320A7072D2B29C07077E08996CE5F093BB8E4200B2C 9B04361A24DC7F37C8BD09A7C51A9D8577168AD021BF2B4AC3D67552F481B1A");

    assert(element_cmp(c, d) == 0);

    t1 = rdtsc();
    for (i = 0; i < N; i++) { element_mul(c, a, b); }
    t2 = rdtsc();

    printf("element mul: %.2lf [clock]\n", (double)(t2 - t1) / N);

    mpz_init_set_str(e, "1B45F16C848B9C476C1D2FF1FD60A0D0C19BBA6F3ECE3CF6C5FCE4FAB7CAD4FF", 16);

    element_pow(c, a, e);
    element_set_str(d, "B40190CE812CB4F668A839952128D19B1748F3BB19E902480D089AF9053A6D2 19DA59F09C3C20472C3BD19A4FC95BCAF266B9D1539AAD23E3C67C4F3A7CA51D");

    assert(element_cmp(c, d) == 0);

    mpz_clear(e);

    //--------------------
    //  sqr
    //--------------------
    element_sqr(c, a);
    element_mul(d, a, a);

    assert(element_cmp(c, d) == 0);

    t1 = rdtsc();
    for (i = 0; i < N; i++) { element_sqr(c, a); }
    t2 = rdtsc();

    printf("element sqr: %.2lf [clock]\n", (double)(t2 - t1) / N);

    //--------------------
    //  random
    //--------------------
    element_random(a);
    element_random(b);

    //--------------------
    //  inv
    //--------------------
    element_mul(c, a, b);
    element_inv(b, b);
    element_mul(c, c, b);
    element_inv(d, a);
    element_mul(d, a, d);

    assert(element_cmp(c, a) == 0);
    assert(element_is_one(d));

    t1 = rdtsc();
    for (i = 0; i < N; i++) { element_inv(b, a); }
    t2 = rdtsc();

    printf("element inv: %.2lf [clock]\n", (double)(t2 - t1) / N);

    //--------------------
    //  pow
    //--------------------
    mpz_init_set_str(exp, loop, 10);

    element_set_one(b);

    for (i = 0; i < atoi(loop); i++) { element_mul(b, b, a); }

    element_pow(c, a, exp);

    assert(element_cmp(b, c) == 0);

    mpz_set(exp, f->order);

    for (i = 0; i < 100; i++)
    {
        element_random(a);
        element_pow(b, a, exp);

        assert(element_cmp(b, a) == 0);
    }

    t1 = rdtsc();
    for (i = 0; i < N; i++) { element_pow(b, a, exp); }
    t2 = rdtsc();

    printf("element pow with order: %.2lf [clock]\n", (double)(t2 - t1) / N);

    mpz_clear(exp);

    //--------------------
    //  clear
    //--------------------
    element_clear(a);
    element_clear(b);
    element_clear(c);
    element_clear(d);
}
Beispiel #5
0
//compute c_i=a_i+b_i at one time.
static void multi_add(element_ptr c[], element_ptr a[], element_ptr b[], int n){
  int i;
  element_t* table = (element_t*)pbc_malloc(sizeof(element_t)*n);  //a big problem?
  point_ptr p, q, r;
  element_t e0, e1, e2;
  curve_data_ptr cdp = (curve_data_ptr)a[0]->field->data;

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

  element_init(table[0], p->x->field);
  element_sub(table[0], q->x, p->x);
  for(i=1; i<n; i++){
	  p = (point_ptr)a[i]->data;
	  q = (point_ptr)b[i]->data;
    element_init(table[i], p->x->field);
    element_sub(table[i], q->x, p->x);
    element_mul(table[i], table[i], table[i-1]);
  }
  element_invert(e2, table[n-1]);
  for(i=n-1; i>0; i--){
	  p = (point_ptr)a[i]->data;
	  q = (point_ptr)b[i]->data;
    element_mul(table[i], table[i-1], e2);
    element_sub(e1, q->x, p->x);
    element_mul(e2,e2,e1); //e2=e2*(x2_j-x1_j)
  }
  element_set(table[0],e2); //e2 no longer used.

  for(i=0; i<n; i++){
	  p = (point_ptr)a[i]->data;
	  q = (point_ptr)b[i]->data;
	  r = (point_ptr)c[i]->data;
    if (p->inf_flag) {
      curve_set(c[i], b[i]);
      continue;
    }
    if (q->inf_flag) {
      curve_set(c[i], a[i]);
      continue;
    }
    if (!element_cmp(p->x, q->x)) { //a[i]=b[i]
      if (!element_cmp(p->y, q->y)) {
        if (element_is0(p->y)) {
          r->inf_flag = 1;
          continue;
        } else {
          double_no_check(r, p, cdp->a);
          continue;
        }
      }
      //points are inverses of each other
      r->inf_flag = 1;
      continue;
    } else {
      //lambda = (y2-y1)/(x2-x1)
      element_sub(e2, q->y, p->y);
      element_mul(e2, e2, table[i]);
      //x3 = lambda^2 - x1 - x2
      element_square(e0, e2);
      element_sub(e0, e0, p->x);
      element_sub(e0, e0, q->x);
      //y3 = (x1-x3)lambda - y1
      element_sub(e1, p->x, e0);
      element_mul(e1, e1, e2);
      element_sub(e1, e1, p->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);
}
Beispiel #6
0
//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);
}
Beispiel #7
0
// 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);
}