aboutsummaryrefslogtreecommitdiffstats
path: root/moon-abe/pbc-0.5.14/ecc
diff options
context:
space:
mode:
Diffstat (limited to 'moon-abe/pbc-0.5.14/ecc')
-rw-r--r--moon-abe/pbc-0.5.14/ecc/a_param.c2315
-rw-r--r--moon-abe/pbc-0.5.14/ecc/curve.c987
-rw-r--r--moon-abe/pbc-0.5.14/ecc/d_param.c1258
-rw-r--r--moon-abe/pbc-0.5.14/ecc/e_param.c1006
-rw-r--r--moon-abe/pbc-0.5.14/ecc/eta_T_3.c835
-rw-r--r--moon-abe/pbc-0.5.14/ecc/f_param.c599
-rw-r--r--moon-abe/pbc-0.5.14/ecc/g_param.c1435
-rw-r--r--moon-abe/pbc-0.5.14/ecc/hilbert.c539
-rw-r--r--moon-abe/pbc-0.5.14/ecc/mnt.c496
-rw-r--r--moon-abe/pbc-0.5.14/ecc/mpc.c122
-rw-r--r--moon-abe/pbc-0.5.14/ecc/mpc.h93
-rw-r--r--moon-abe/pbc-0.5.14/ecc/pairing.c283
-rw-r--r--moon-abe/pbc-0.5.14/ecc/param.c220
-rw-r--r--moon-abe/pbc-0.5.14/ecc/param.h23
-rw-r--r--moon-abe/pbc-0.5.14/ecc/singular.c447
15 files changed, 0 insertions, 10658 deletions
diff --git a/moon-abe/pbc-0.5.14/ecc/a_param.c b/moon-abe/pbc-0.5.14/ecc/a_param.c
deleted file mode 100644
index 6cf8dd96..00000000
--- a/moon-abe/pbc-0.5.14/ecc/a_param.c
+++ /dev/null
@@ -1,2315 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h> //for rand, pbc_malloc, pbc_free
-#include <string.h> //for strcmp
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_fp.h"
-#include "pbc_fieldquadratic.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_curve.h"
-#include "pbc_random.h"
-#include "pbc_memory.h"
-#include "ecc/param.h"
-#include "pbc_a_param.h"
-#include "pbc_a1_param.h"
-
-typedef struct {
- int exp2;
- int exp1;
- int sign1;
- int sign0;
- mpz_t r; // r = 2^exp2 + sign1 * 2^exp1 + sign0 * 1
- mpz_t q; // we work in E(F_q) (and E(F_q^2))
- mpz_t h; // r * h = q + 1
-} *a_param_ptr;
-
-typedef struct {
- field_t Fq, Fq2, Eq;
- int exp2, exp1;
- int sign1;
-} *a_pairing_data_ptr;
-
-static void a_out_str(FILE *stream, void *data) {
- a_param_ptr p = data;
- param_out_type(stream, "a");
- param_out_mpz(stream, "q", p->q);
- param_out_mpz(stream, "h", p->h);
- param_out_mpz(stream, "r", p->r);
- param_out_int(stream, "exp2", p->exp2);
- param_out_int(stream, "exp1", p->exp1);
- param_out_int(stream, "sign1", p->sign1);
- param_out_int(stream, "sign0", p->sign0);
-}
-
-static void a_clear(void *data) {
- a_param_ptr sp = data;
- mpz_clear(sp->r);
- mpz_clear(sp->q);
- mpz_clear(sp->h);
- pbc_free(data);
-}
-
-static void phi_identity(element_ptr out, element_ptr in, pairing_ptr pairing) {
- UNUSED_VAR(pairing);
- element_set(out, in);
-}
-
-static void compute_abc_tangent(element_ptr a, element_ptr b, element_ptr c,
- element_ptr Vx, element_ptr Vy, element_ptr e0) {
- //a = -slope_tangent(V.x, V.y);
- //b = 1;
- //c = -(V.y + aV.x);
- //but we multiply by -2*V.y to avoid division so:
- //a = -(3 Vx^2 + cc->a)
- //b = 2 * Vy
- //c = -(2 Vy^2 + a Vx);
- element_square(a, Vx);
- //element_mul_si(a, a, 3);
- element_add(e0, a, a);
- element_add(a, e0, a);
- element_set1(b);
- element_add(a, a, b);
- element_neg(a, a);
-
- element_double(b, Vy);
-
- element_mul(e0, b, Vy);
- element_mul(c, a, Vx);
- element_add(c, c, e0);
- element_neg(c, c);
-}
-
-static void compute_abc_tangent_proj(element_ptr a, element_ptr b, element_ptr c,
- element_ptr Vx, element_ptr Vy,
- element_ptr z, element_ptr z2, element_ptr e0) {
- //a = -(3x^2 + cca z^4)
- //for this case cca = 1
- //b = 2 y z^3
- //c = -(2 y^2 + x a)
- //a = z^2 a
- element_square(a, z2);
- element_square(b, Vx);
- ////element_mul_si(b, b, 3);
- element_double(e0, b);
- element_add(b, e0, b);
- element_add(a, a, b);
- element_neg(a, a);
-
- ////element_mul_si(e0, Vy, 2);
- element_double(e0, Vy);
- element_mul(b, e0, z2);
- element_mul(b, b, z);
-
- element_mul(c, Vx, a);
- element_mul(a, a, z2);
- element_mul(e0, e0, Vy);
- element_add(c, c, e0);
- element_neg(c, c);
-}
-
-static void compute_abc_line(element_ptr a, element_ptr b, element_ptr c,
- element_ptr Vx, element_ptr Vy,
- element_ptr V1x, element_ptr V1y,
- element_ptr 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, so
- //a = -(By - Ay)
- //b = Bx - Ax
- //c = -(Ay b + a Ax);
- element_sub(a, Vy, V1y);
- element_sub(b, V1x, Vx);
- element_mul(c, Vx, V1y);
- element_mul(e0, Vy, V1x);
- element_sub(c, c, e0);
-}
-
-struct pp_coeff_s {
- element_t a;
- element_t b;
- element_t c;
-};
-typedef struct pp_coeff_s pp_coeff_t[1];
-typedef struct pp_coeff_s *pp_coeff_ptr;
-
-static void pp_coeff_set(pp_coeff_ptr p, element_t a, element_t b, element_t c) {
- element_init(p->a, a->field);
- element_init(p->b, b->field);
- element_init(p->c, c->field);
- element_set(p->a, a);
- element_set(p->b, b);
- element_set(p->c, c);
-}
-
-static void a_pairing_pp_init(pairing_pp_t p, element_ptr in1, pairing_t pairing) {
- int i, n;
- a_pairing_data_ptr ainfo = pairing->data;
- p->data = pbc_malloc(sizeof(pp_coeff_t) * (ainfo->exp2 + 1));
- pp_coeff_t *coeff = (pp_coeff_t *) p->data;
- element_t V, V1;
- element_t a, b, c;
- element_t e0;
- element_ptr Vx, Vy;
- element_ptr V1x, V1y;
-
- #define do_tangent() \
- compute_abc_tangent(a, b, c, Vx, Vy, e0); \
- pp_coeff_set(coeff[i], a, b, c);
-
- #define do_line() \
- compute_abc_line(a, b, c, Vx, Vy, V1x, V1y, e0); \
- pp_coeff_set(coeff[i], a, b, c);
-
- element_init(V, ainfo->Eq);
- element_init(V1, ainfo->Eq);
- element_set(V, in1);
- Vx = curve_x_coord(V);
- Vy = curve_y_coord(V);
- V1x = curve_x_coord(V1);
- V1y = curve_y_coord(V1);
- element_init(e0, ainfo->Fq);
- element_init(a, ainfo->Fq);
- element_init(b, ainfo->Fq);
- element_init(c, ainfo->Fq);
-
- n = ainfo->exp1;
- for (i=0; i<n; i++) {
- do_tangent();
- element_double(V, V);
- }
-
- if (ainfo->sign1 < 0) {
- element_neg(V1, V);
- } else {
- element_set(V1, V);
- }
- n = ainfo->exp2;
- for (; i<n; i++) {
- do_tangent();
- element_double(V, V);
- }
-
- do_line();
-
- element_clear(e0);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(V);
- element_clear(V1);
- #undef do_tangent
- #undef do_line
-}
-
-static void a_pairing_pp_clear(pairing_pp_t p) {
- a_pairing_data_ptr ainfo = p->pairing->data;
- pp_coeff_t *coeff = (pp_coeff_t *) p->data;
- int i, n = ainfo->exp2 + 1;
- for (i=0; i<n; i++) {
- pp_coeff_ptr pp = coeff[i];
- element_clear(pp->a);
- element_clear(pp->b);
- element_clear(pp->c);
- }
- pbc_free(p->data);
-}
-
-// Requires cofactor to be odd.
-// Overwrites in and temp, out != in.
-// Luckily this touchy routine is only used internally.
-// TODO: rewrite to allow (out == in)? would simplify a_finalpow()
-static void lucas_odd(element_ptr out, element_ptr in, element_ptr temp, mpz_t cofactor) {
- 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);
- int 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 + 1) / r is even
- //(r should be odd and q + 1 is always even)
- //thus v0 = V_k, v1 = V_{k+1}
- //and V_{k-1} = P v0 - v1
-
- //so U_k = (P V_k - 2 V_{k-1}) / (P^2 - 4)
- // = (2 v1 - P v0) / (P^2 - 4)
-
- element_mul(in0, v0, t1);
- element_double(v1, v1);
- element_sub(v1, v1, in0);
-
- element_square(t1, t1);
- element_sub(t1, t1, t0);
- element_sub(t1, t1, t0);
- element_div(v1, v1, t1);
-
- element_halve(v0, v0);
- element_mul(v1, v1, in1);
-}
-
-static inline void a_tateexp(element_ptr out, element_ptr in, element_ptr temp, mpz_t cofactor) {
- element_ptr in1 = element_y(in);
- //simpler but slower:
- //element_pow_mpz(out, f, tateexp);
-
- //1. Exponentiate by q-1
- //which is equivalent to the following
-
- element_invert(temp, in);
- element_neg(in1, in1);
- element_mul(in, in, temp);
-
- //2. Exponentiate by (q+1)/r
-
- //Instead of:
- // element_pow_mpz(out, in, cofactor);
- //we use Lucas sequences (see "Compressed Pairings", Scott and Barreto)
- lucas_odd(out, in, temp, cofactor);
-}
-
-//computes a Qx + b Qy + c for type A pairing
-static inline void a_miller_evalfn(element_ptr out,
- element_ptr a, element_ptr b, element_ptr c,
- element_ptr Qx, element_ptr Qy) {
- //we'll map Q via (x,y) --> (-x, iy)
- //hence Re(a Qx + b Qy + c) = -a Q'x + c and
- //Im(a Qx + b Qy + c) = b Q'y
- element_mul(element_y(out), a, Qx);
- element_sub(element_x(out), c, element_y(out));
- element_mul(element_y(out), b, Qy);
-}
-
-static void a_pairing_pp_apply(element_ptr out, element_ptr in2, pairing_pp_t p) {
- //TODO: use proj coords here too to shave off a little time
- element_ptr Qx = curve_x_coord(in2);
- element_ptr Qy = curve_y_coord(in2);
- element_t f, f0;
- int i, n;
- a_pairing_data_ptr ainfo = p->pairing->data;
- pp_coeff_t *coeff = p->data;
- element_init(f, ainfo->Fq2);
- element_init(f0, ainfo->Fq2);
-
- element_set1(f);
- n = ainfo->exp1;
- for (i=0; i<n; i++) {
- pp_coeff_ptr pp = coeff[i];
- element_square(f, f);
- a_miller_evalfn(f0, pp->a, pp->b, pp->c, Qx, Qy);
- element_mul(f, f, f0);
- }
- if (ainfo->sign1 < 0) {
- element_invert(out, f);
- } else {
- element_set(out, f);
- }
- n = ainfo->exp2;
- for (; i<n; i++) {
- element_square(f, f);
- pp_coeff_ptr pp = coeff[i];
- a_miller_evalfn(f0, pp->a, pp->b, pp->c, Qx, Qy);
- element_mul(f, f, f0);
- }
-
- element_mul(f, f, out);
- {
- pp_coeff_ptr pp = coeff[i];
- a_miller_evalfn(f0, pp->a, pp->b, pp->c, Qx, Qy);
- element_mul(f, f, f0);
- }
-
- a_tateexp(out, f, f0, p->pairing->phikonr);
-
- element_clear(f);
- element_clear(f0);
-}
-
-// in1, in2 are from E(F_q), out from F_q^2.
-// Pairing via elliptic nets (see Stange).
-static void a_pairing_ellnet(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- 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);
-
- //we map (x2,y2) to (-x2, i y2) before pairing
- //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
- // c0 = 1
- // cm2 = -1
- // cm3 = -2y
- element_double(c1, y);
- element_set1(c0);
- element_neg(cm3, c1);
- element_neg(cm2, c0);
-
- // a = 1, b = 0 for Y^2 = X^3 + X
- //hence c3 = c_{k+3} = c_4 = 4y(x^6 + 5(x^4 - x^2) - 1)
- //use cm1, C, c2 as temp variables for now
- element_square(cm1, x);
- element_square(C, cm1);
- element_sub(c2, C, cm1);
- element_double(c3, c2);
- element_double(c3, c3);
- element_add(c3, c3, c2);
- element_mul(c2, C, cm1);
- element_add(c3, c3, c2);
- element_add(c3, c3, cm2);
- element_mul(c3, c3, c1);
- element_double(c3, c3);
-
- // c2 = c_3 = 3x^4 + 6x^2 - 1
- element_double(cm1, cm1);
- element_add(cm1, cm1, C);
- element_double(C, cm1);
- element_add(C, C, cm1);
- element_add(c2, C, cm2);
-
- // 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)
- //(recall phi takes x2 to -x2, y2 to i y2)
- element_add(A, x, x2);
- element_double(C, x);
- element_sub(C, C, x2);
- element_square(cm1, A);
- element_mul(cm1, C, cm1);
- element_set(element_x(d1), y);
- element_set(element_y(d1), y2);
- element_square(d1, d1);
- element_sub(element_x(d1), element_x(d1), cm1);
- element_neg(B, d1);
- element_invert(B, B);
- element_invert(A, A);
- element_mul(element_x(d1), y, A);
- element_neg(element_x(d1), element_x(d1));
- element_mul(element_y(d1), y2, A);
- element_square(d1, d1);
- element_sub(element_x(d1), C, element_x(d1));
- element_neg(element_y(d1), element_y(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(element_x(out), element_x(u), t0);
- element_mul(element_y(out), element_y(u), t0);
- element_mul(element_x(dm1), element_x(v), s0);
- element_mul(element_y(dm1), element_y(v), s0);
- element_sub(dm1, dm1, out);
-
- element_mul(element_x(out), element_x(u), t1);
- element_mul(element_y(out), element_y(u), t1);
- element_mul(element_x(d0), element_x(v), s1);
- element_mul(element_y(d0), element_y(v), s1);
- element_sub(d0, d0, out);
- element_mul(element_x(d0), element_x(d0), A);
- element_mul(element_y(d0), element_y(d0), A);
-
- element_mul(element_x(out), element_x(u), t2);
- element_mul(element_y(out), element_y(u), t2);
- element_mul(element_x(d1), element_x(v), s2);
- element_mul(element_y(d1), element_y(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(element_x(out), element_x(u), tm1);
- element_mul(element_y(out), element_y(u), tm1);
- element_mul(element_x(dm1), element_x(v), sm1);
- element_mul(element_y(dm1), element_y(v), sm1);
- element_sub(dm1, dm1, out);
-
- element_mul(element_x(out), element_x(u), t0);
- element_mul(element_y(out), element_y(u), t0);
- element_mul(element_x(d0), element_x(v), s0);
- element_mul(element_y(d0), element_y(v), s0);
- element_sub(d0, d0, out);
-
- element_mul(element_x(out), element_x(u), t1);
- element_mul(element_y(out), element_y(u), t1);
- element_mul(element_x(d1), element_x(v), s1);
- element_mul(element_y(d1), element_y(v), s1);
- element_sub(d1, d1, out);
- element_mul(element_x(d1), element_x(d1), A);
- element_mul(element_y(d1), element_y(d1), A);
- }
- if (!m) break;
- m--;
- }
- // since c_k lies base field
- // it gets killed by the final powering
- //element_invert(c1, c1);
- //element_mul(element_x(d1), element_x(d1), c1);
- //element_mul(element_y(d1), element_y(d1), c1);
-
- a_tateexp(out, d1, d0, 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);
-}
-
-struct ellnet_pp_st_s {
- element_t sm1, s0, s1, s2;
- element_t tm1, t0, t1, t2;
-};
-typedef struct ellnet_pp_st_s ellnet_pp_st_t[1];
-typedef struct ellnet_pp_st_s *ellnet_pp_st_ptr;
-
-struct ellnet_pp_s {
- element_t x;
- element_t y;
- ellnet_pp_st_t *seq;
-};
-typedef struct ellnet_pp_s ellnet_pp_t[1];
-typedef struct ellnet_pp_s *ellnet_pp_ptr;
-
-static void a_pairing_ellnet_pp_init(pairing_pp_t p, element_ptr in1, pairing_t pairing) {
- element_ptr x = curve_x_coord(in1);
- element_ptr y = curve_y_coord(in1);
- int i, rbits = mpz_sizeinbase(pairing->r, 2);
- ellnet_pp_ptr pp = p->data = pbc_malloc(sizeof(ellnet_pp_t));
- pp->seq = pbc_malloc(sizeof(ellnet_pp_st_t) * rbits);
- element_init_same_as(pp->x, x);
- element_init_same_as(pp->y, y);
- element_set(pp->x, x);
- element_set(pp->y, y);
- for (i=0; i<rbits; i++) {
- ellnet_pp_st_ptr seq = pp->seq[i];
- element_init_same_as(seq->sm1, x);
- element_init_same_as(seq->s0, x);
- element_init_same_as(seq->s1, x);
- element_init_same_as(seq->s2, x);
- element_init_same_as(seq->tm1, x);
- element_init_same_as(seq->t0, x);
- element_init_same_as(seq->t1, x);
- element_init_same_as(seq->t2, x);
- }
-
- //we map (x2,y2) to (-x2, i y2) before pairing
- //notation: cmi means c_{k-i}, ci means c_{k+i}
- element_t cm3, cm2, cm1, c0, c1, c2, c3, c4;
- element_t 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);
-
- // c1 = 2y
- // c0 = 1
- // cm2 = -1
- // cm3 = -2y
- element_double(c1, y);
- element_set1(c0);
- element_neg(cm3, c1);
- element_neg(cm2, c0);
-
- // a = 1, b = 0 for Y^2 = X^3 + X
- //hence c3 = c_{k+3} = c_4 = 4y(x^6 + 5(x^4 - x^2) - 1)
- //use cm1, C, c2 as temp variables for now
- element_square(cm1, x);
- element_square(C, cm1);
- element_sub(c2, C, cm1);
- element_double(c3, c2);
- element_double(c3, c3);
- element_add(c3, c3, c2);
- element_mul(c2, C, cm1);
- element_add(c3, c3, c2);
- element_add(c3, c3, cm2);
- element_mul(c3, c3, c1);
- element_double(c3, c3);
-
- // c2 = c_3 = 3x^4 + 6x^2 - 1
- element_double(cm1, cm1);
- element_add(cm1, cm1, C);
- element_double(C, cm1);
- element_add(C, C, cm1);
- element_add(c2, C, cm2);
-
- // 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);
-
- // cm1 = 0
- // C = (2y)^-1
- element_set0(cm1);
- element_invert(C, c1);
-
- int k = 0;
- element_t sm2, s3;
- element_t tm2, t3;
- element_ptr sm1, s0, s1, s2;
- element_ptr tm1, t0, t1, t2;
- element_t e0, e1;
-
- element_init_same_as(sm2, x);
- element_init_same_as(s3, x);
-
- element_init_same_as(tm2, x);
- element_init_same_as(t3, x);
-
- element_init_same_as(e0, x);
- element_init_same_as(e1, x);
-
- int m = rbits - 2;
- for (;;) {
- ellnet_pp_st_ptr seq = pp->seq[k];
- sm1 = seq->sm1;
- s0 = seq->s0;
- s1 = seq->s1;
- s2 = seq->s2;
- tm1 = seq->tm1;
- t0 = seq->t0;
- t1 = seq->t1;
- t2 = seq->t2;
-
- 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);
-
- if (!m) break;
- k++;
-
- 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);
-
- } 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);
- }
- m--;
- }
-
- 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(s3);
-
- element_clear(tm2);
- element_clear(t3);
-
- element_clear(e0);
- element_clear(e1);
- element_clear(C);
-}
-
-static void a_pairing_ellnet_pp_clear(pairing_pp_t p) {
- ellnet_pp_ptr pp = p->data;
- int i, rbits = mpz_sizeinbase(p->pairing->r, 2);
- for (i=0; i<rbits; i++) {
- ellnet_pp_st_ptr seq = pp->seq[i];
- element_clear(seq->sm1);
- element_clear(seq->s0);
- element_clear(seq->s1);
- element_clear(seq->s2);
- element_clear(seq->tm1);
- element_clear(seq->t0);
- element_clear(seq->t1);
- element_clear(seq->t2);
- }
- element_clear(pp->x);
- element_clear(pp->y);
- pbc_free(pp->seq);
- pbc_free(p->data);
-}
-
-static void a_pairing_ellnet_pp_apply(element_ptr out, element_ptr in2, pairing_pp_t p) {
- element_ptr x2 = curve_x_coord(in2);
- element_ptr y2 = curve_y_coord(in2);
- ellnet_pp_ptr pp = p->data;
- int rbits = mpz_sizeinbase(p->pairing->r, 2);
- int k = 0;
- int m = rbits - 2;
- element_t A, B;
- element_t e0, e1;
- element_t dm1, d0, d1;
- element_t u, v;
-
- element_init_same_as(A, x2);
- element_init_same_as(B, out);
- element_init_same_as(e0, x2);
- element_init_same_as(e1, x2);
- element_init_same_as(dm1, out);
- element_init_same_as(d0, out);
- element_init_same_as(d1, out);
- element_init_same_as(u, out);
- element_init_same_as(v, out);
-
- element_add(A, pp->x, x2);
- element_double(e0, pp->x);
- element_sub(e0, e0, x2);
- element_square(e1, A);
- element_mul(e1, e0, e1);
- element_set(element_x(d1), pp->y);
- element_set(element_y(d1), y2);
- element_square(d1, d1);
- element_sub(element_x(d1), element_x(d1), e1);
- element_neg(B, d1);
- element_invert(B, B);
- element_invert(A, A);
- element_mul(element_x(d1), pp->y, A);
- element_neg(element_x(d1), element_x(d1));
- element_mul(element_y(d1), y2, A);
- element_square(d1, d1);
- element_sub(element_x(d1), e0, element_x(d1));
- element_neg(element_y(d1), element_y(d1));
-
- element_set1(dm1);
- element_set1(d0);
- for (;;) {
- element_ptr sm1, s0, s1, s2;
- element_ptr tm1, t0, t1, t2;
- ellnet_pp_st_ptr seq = pp->seq[k];
- sm1 = seq->sm1;
- s0 = seq->s0;
- s1 = seq->s1;
- s2 = seq->s2;
- tm1 = seq->tm1;
- t0 = seq->t0;
- t1 = seq->t1;
- t2 = seq->t2;
- k++;
-
- element_square(u, d0);
- element_mul(v, dm1, d1);
-
- if (mpz_tstbit(p->pairing->r, m)) {
- //double-and-add
- element_mul(element_x(out), element_x(u), t0);
- element_mul(element_y(out), element_y(u), t0);
- element_mul(element_x(dm1), element_x(v), s0);
- element_mul(element_y(dm1), element_y(v), s0);
- element_sub(dm1, dm1, out);
-
- element_mul(element_x(out), element_x(u), t1);
- element_mul(element_y(out), element_y(u), t1);
- element_mul(element_x(d0), element_x(v), s1);
- element_mul(element_y(d0), element_y(v), s1);
- element_sub(d0, d0, out);
- element_mul(element_x(d0), element_x(d0), A);
- element_mul(element_y(d0), element_y(d0), A);
-
- element_mul(element_x(out), element_x(u), t2);
- element_mul(element_y(out), element_y(u), t2);
- element_mul(element_x(d1), element_x(v), s2);
- element_mul(element_y(d1), element_y(v), s2);
- element_sub(d1, d1, out);
- element_mul(d1, d1, B);
- } else {
- //double
- element_mul(element_x(out), element_x(u), tm1);
- element_mul(element_y(out), element_y(u), tm1);
- element_mul(element_x(dm1), element_x(v), sm1);
- element_mul(element_y(dm1), element_y(v), sm1);
- element_sub(dm1, dm1, out);
-
- element_mul(element_x(out), element_x(u), t0);
- element_mul(element_y(out), element_y(u), t0);
- element_mul(element_x(d0), element_x(v), s0);
- element_mul(element_y(d0), element_y(v), s0);
- element_sub(d0, d0, out);
-
- element_mul(element_x(out), element_x(u), t1);
- element_mul(element_y(out), element_y(u), t1);
- element_mul(element_x(d1), element_x(v), s1);
- element_mul(element_y(d1), element_y(v), s1);
- element_sub(d1, d1, out);
- element_mul(element_x(d1), element_x(d1), A);
- element_mul(element_y(d1), element_y(d1), A);
- }
- if (!m) break;
- m--;
- }
- a_tateexp(out, d1, d0, p->pairing->phikonr);
-
- element_clear(A);
- element_clear(B);
- element_clear(e0);
- element_clear(e1);
- element_clear(dm1);
- element_clear(d0);
- element_clear(d1);
- element_clear(u);
- element_clear(v);
-}
-
-//in1, in2 are from E(F_q), out from F_q^2
-static void a_pairing_proj(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- a_pairing_data_ptr p = pairing->data;
- element_t V, V1;
- element_t z, z2;
- element_t f, f0, f1;
- element_t a, b, c;
- element_t e0;
- const element_ptr e1 = a, e2 = b, e3 = c;
- int i, n;
- element_ptr Vx, Vy;
- element_ptr V1x, V1y;
- element_ptr Qx = curve_x_coord(in2);
- element_ptr Qy = curve_y_coord(in2);
-
- //could save a couple of inversions by avoiding
- //this function and rewriting do_line() to handle projective coords
- //convert V from weighted projective (Jacobian) to affine
- //i.e. (X, Y, Z) --> (X/Z^2, Y/Z^3)
- //also sets z to 1
- #define point_to_affine() \
- element_invert(z, z); \
- element_square(e0, z); \
- element_mul(Vx, Vx, e0); \
- element_mul(e0, e0, z); \
- element_mul(Vy, Vy, e0); \
- element_set1(z); \
- element_set1(z2);
-
- #define proj_double() { \
- /* e0 = 3x^2 + (cc->a) z^4 */ \
- /* for this case a = 1 */ \
- element_square(e0, Vx); \
- /*element_mul_si(e0, e0, 3);*/ \
- element_double(e1, e0); \
- element_add(e0, e1, e0); \
- element_square(e1, z2); \
- element_add(e0, e0, e1); \
- \
- /* z_out = 2 y z */ \
- element_mul(z, Vy, z); \
- /*element_mul_si(z, z, 2);*/ \
- element_double(z, z); \
- element_square(z2, z); \
- \
- /* e1 = 4 x y^2 */ \
- element_square(e2, Vy); \
- element_mul(e1, Vx, e2); \
- /*element_mul_si(e1, e1, 4);*/ \
- element_double(e1, e1); \
- element_double(e1, e1); \
- \
- /* x_out = e0^2 - 2 e1 */ \
- element_double(e3, e1); \
- element_square(Vx, e0); \
- element_sub(Vx, Vx, 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, Vx); \
- element_mul(e0, e0, e1); \
- element_sub(Vy, e0, e2); \
- }
-
- #define do_tangent() \
- compute_abc_tangent_proj(a, b, c, Vx, Vy, z, z2, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0);
-
- #define do_line() \
- compute_abc_line(a, b, c, Vx, Vy, V1x, V1y, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0);
-
- element_init(V, p->Eq);
- element_init(V1, p->Eq);
- element_set(V, in1);
-
- Vx = curve_x_coord(V);
- Vy = curve_y_coord(V);
- V1x = curve_x_coord(V1);
- V1y = curve_y_coord(V1);
-
- element_init(f, p->Fq2);
- element_init(f0, p->Fq2);
- element_init(f1, p->Fq2);
- element_set1(f);
- element_init(a, p->Fq);
- element_init(b, p->Fq);
- element_init(c, p->Fq);
- element_init(e0, p->Fq);
- element_init(z, p->Fq);
- element_init(z2, p->Fq);
- element_set1(z);
- element_set1(z2);
- n = p->exp1;
- for (i=0; i<n; i++) {
- //f = f^2 g_V,V(Q)
- //where g_V,V = tangent at V
- element_square(f, f);
- do_tangent();
- proj_double();
- }
- point_to_affine();
- if (p->sign1 < 0) {
- element_neg(V1, V);
- element_invert(f1, f);
- } else {
- element_set(V1, V);
- element_set(f1, f);
- }
- n = p->exp2;
- for (; i<n; i++) {
- element_square(f, f);
- do_tangent();
- proj_double();
- }
-
- element_mul(f, f, f1);
- point_to_affine();
- do_line();
-
- a_tateexp(out, f, f0, pairing->phikonr);
-
- element_clear(f);
- element_clear(f0);
- element_clear(f1);
- element_clear(z);
- element_clear(z2);
- element_clear(V);
- element_clear(V1);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(e0);
- #undef point_to_affine
- #undef proj_double
- #undef do_tangent
- #undef do_line
-}
-
-//in1, in2 are from E(F_q), out from F_q^2
-static void a_pairing_affine(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- a_pairing_data_ptr p = pairing->data;
- element_t V, V1;
- element_t f, f0, f1;
- element_t a, b, c;
- element_t e0;
- int i, n;
- element_ptr Qx = curve_x_coord(in2);
- element_ptr Qy = curve_y_coord(in2);
- element_ptr Vx, Vy;
- element_ptr V1x, V1y;
-
- #define do_tangent() \
- compute_abc_tangent(a, b, c, Vx, Vy, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0);
-
- #define do_line() \
- compute_abc_line(a, b, c, Vx, Vy, V1x, V1y, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0);
-
- element_init(V, p->Eq);
- element_init(V1, p->Eq);
- Vx = curve_x_coord(V);
- Vy = curve_y_coord(V);
-
- V1x = curve_x_coord(V1);
- V1y = curve_y_coord(V1);
-
- element_set(V, in1);
- element_init(f, p->Fq2);
- element_init(f0, p->Fq2);
- element_init(f1, p->Fq2);
- element_set1(f);
- element_init(a, p->Fq);
- element_init(b, p->Fq);
- element_init(c, p->Fq);
- element_init(e0, p->Fq);
- n = p->exp1;
- for (i=0; i<n; i++) {
- //f = f^2 g_V,V(Q)
- //where g_V,V = tangent at V
- element_square(f, f);
- do_tangent();
- element_double(V, V);
- }
- if (p->sign1 < 0) {
- element_neg(V1, V);
- element_invert(f1, f);
- } else {
- element_set(V1, V);
- element_set(f1, f);
- }
- n = p->exp2;
- for (; i<n; i++) {
- element_square(f, f);
- do_tangent();
- element_double(V, V);
- }
-
- element_mul(f, f, f1);
- do_line();
-
- a_tateexp(out, f, f0, pairing->phikonr);
-
- element_clear(f);
- element_clear(f0);
- element_clear(f1);
- element_clear(V);
- element_clear(V1);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(e0);
- #undef do_tangent
- #undef do_line
-}
-
-// On Computing Products of Pairing
-//in1, in2 are from E(F_q), out from F_q^2
-void a_pairings_affine(element_ptr out, element_t in1[], element_t in2[],
- int n_prod, pairing_t pairing) {
- a_pairing_data_ptr p = pairing->data;
- element_t* V = pbc_malloc(sizeof(element_t)*n_prod);
- element_t* V1 = pbc_malloc(sizeof(element_t)*n_prod);
- element_t f, f0, f1;
- element_t a, b, c;
- element_t e0;
- int i, j, n;
- element_ptr Qx, Qy;
- element_ptr Vx, Vy;
- element_ptr V1x, V1y;
-
- #define do_tangents() \
- for(j=0; j<n_prod; j++){ \
- Vx = curve_x_coord(V[j]); \
- Vy = curve_y_coord(V[j]); \
- Qx = curve_x_coord(in2[j]); \
- Qy = curve_y_coord(in2[j]); \
- \
- compute_abc_tangent(a, b, c, Vx, Vy, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- }
-
- #define do_lines() \
- for(j=0;j<n_prod;j++){ \
- Vx = curve_x_coord(V[j]); \
- Vy = curve_y_coord(V[j]); \
- V1x = curve_x_coord(V1[j]); \
- V1y = curve_y_coord(V1[j]); \
- Qx = curve_x_coord(in2[j]); \
- Qy = curve_y_coord(in2[j]); \
- \
- compute_abc_line(a, b, c, Vx, Vy, V1x, V1y, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- }
-
- for(i=0; i<n_prod; i++){
- element_init(V[i],p->Eq);
- element_init(V1[i],p->Eq);
- element_set(V[i],in1[i]);
- }
-
-
- element_init(f, p->Fq2);
- element_init(f0, p->Fq2);
- element_init(f1, p->Fq2);
- element_set1(f);
- element_init(a, p->Fq);
- element_init(b, p->Fq);
- element_init(c, p->Fq);
- element_init(e0, p->Fq);
- n = p->exp1;
- for (i=0; i<n; i++) {
- //f = f^2 g_V,V(Q)
- //where g_V,V = tangent at V
- element_square(f, f);
- do_tangents();
- element_multi_double(V, V, n_prod); //V_i = V_i + V_i for all i at one time.
- }
- if (p->sign1 < 0) {
- for(j=0; j<n_prod; j++){
- element_neg(V1[j], V[j]);
- }
- element_invert(f1, f);
- } else {
- for(j=0; j<n_prod; j++){
- element_set(V1[j], V[j]);
- }
- element_set(f1, f);
- }
- n = p->exp2;
- for (; i<n; i++) {
- element_square(f, f);
- do_tangents();
- element_multi_double(V, V, n_prod);
- }
-
- element_mul(f, f, f1);
- do_lines();
-
- a_tateexp(out, f, f0, pairing->phikonr);
-
- element_clear(f);
- element_clear(f0);
- element_clear(f1);
- for(j=0;j<n_prod;j++){
- element_clear(V[j]);
- element_clear(V1[j]);
- }
- pbc_free(V);
- pbc_free(V1);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(e0);
- #undef do_tangents
- #undef do_lines
-}
-
-static void a_pairing_clear(pairing_t pairing) {
- field_clear(pairing->GT);
-
- a_pairing_data_ptr p = pairing->data;
- field_clear(p->Eq);
- field_clear(p->Fq);
- field_clear(p->Fq2);
- pbc_free(p);
-
- mpz_clear(pairing->r);
- mpz_clear(pairing->phikonr);
- field_clear(pairing->Zr);
-}
-
-static void a_pairing_option_set(pairing_t pairing, char *key, char *value) {
- if (!strcmp(key, "method")) {
- if (!strcmp(value, "miller")) {
- pairing->map = a_pairing_proj;
- pairing->pp_init = a_pairing_pp_init;
- pairing->pp_clear = a_pairing_pp_clear;
- pairing->pp_apply = a_pairing_pp_apply;
- } else if (!strcmp(value, "miller-affine")) {
- pairing->map = a_pairing_affine;
- pairing->pp_init = a_pairing_pp_init;
- pairing->pp_clear = a_pairing_pp_clear;
- pairing->pp_apply = a_pairing_pp_apply;
- } else if (!strcmp(value, "shipsey-stange")) {
- pairing->map = a_pairing_ellnet;
- pairing->pp_init = a_pairing_ellnet_pp_init;
- pairing->pp_clear = a_pairing_ellnet_pp_clear;
- pairing->pp_apply = a_pairing_ellnet_pp_apply;
- }
- }
-}
-
-static void a_finalpow(element_t e) {
- pairing_ptr pairing = e->field->pairing;
- element_t t0, t1;
- element_init_same_as(t0, e->data);
- element_init_same_as(t1, e->data);
- a_tateexp(t0, e->data, t1, pairing->phikonr);
- element_set(e->data, t0);
- element_clear(t0);
- element_clear(t1);
-}
-
-static void a_init_pairing(pairing_ptr pairing, void *data) {
- a_param_ptr param = data;
- element_t a, b;
- a_pairing_data_ptr p;
-
- p = pairing->data = pbc_malloc(sizeof(*p));
- p->exp2 = param->exp2;
- p->exp1 = param->exp1;
- p->sign1 = param->sign1;
- mpz_init(pairing->r);
- mpz_set(pairing->r, param->r);
- field_init_fp(pairing->Zr, pairing->r);
- pairing->map = a_pairing_proj;
- pairing->prod_pairings = a_pairings_affine;
-
- field_init_fp(p->Fq, param->q);
- element_init(a, p->Fq);
- element_init(b, p->Fq);
- element_set1(a);
- element_set0(b);
- field_init_curve_ab(p->Eq, a, b, pairing->r, param->h);
- element_clear(a);
- element_clear(b);
-
- field_init_fi(p->Fq2, p->Fq);
-
- //k=2, hence phi_k(q) = q + 1, phikonr = (q+1)/r
- mpz_init(pairing->phikonr);
- mpz_set(pairing->phikonr, param->h);
-
- pairing->G1 = p->Eq;
- pairing->G2 = pairing->G1;
- pairing->phi = phi_identity;
- pairing_GT_init(pairing, p->Fq2);
- pairing->finalpow = a_finalpow;
-
- pairing->clear_func = a_pairing_clear;
- pairing->option_set = a_pairing_option_set;
- pairing->pp_init = a_pairing_pp_init;
- pairing->pp_clear = a_pairing_pp_clear;
- pairing->pp_apply = a_pairing_pp_apply;
-}
-
-static void a_param_init(pbc_param_ptr par) {
- static pbc_param_interface_t interface = {{
- a_clear,
- a_init_pairing,
- a_out_str,
- }};
- par->api = interface;
- a_param_ptr p = par->data = pbc_malloc(sizeof(*p));
- mpz_init(p->r);
- mpz_init(p->q);
- mpz_init(p->h);
-}
-
-// Public interface for type A pairings:
-
-int pbc_param_init_a(pbc_param_ptr par, struct symtab_s *tab) {
- a_param_init(par);
- a_param_ptr p = par->data;
-
- int err = 0;
- err += lookup_mpz(p->q, tab, "q");
- err += lookup_mpz(p->r, tab, "r");
- err += lookup_mpz(p->h, tab, "h");
- err += lookup_int(&p->exp2, tab, "exp2");
- err += lookup_int(&p->exp1, tab, "exp1");
- err += lookup_int(&p->sign1, tab, "sign1");
- err += lookup_int(&p->sign0, tab, "sign0");
- return err;
-}
-
-void pbc_param_init_a_gen(pbc_param_ptr par, int rbits, int qbits) {
- a_param_init(par);
- a_param_ptr sp = par->data;
- int found = 0;
-
- mpz_ptr q = sp->q;
- mpz_ptr r = sp->r;
- mpz_ptr h = sp->h;
-
- do {
- int i;
- mpz_set_ui(r, 0);
-
- if (rand() % 2) {
- sp->exp2 = rbits - 1;
- sp->sign1 = 1;
- } else {
- sp->exp2 = rbits;
- sp->sign1 = -1;
- }
- mpz_setbit(r, sp->exp2);
-
- //use q as a temp variable
- mpz_set_ui(q, 0);
- sp->exp1 = (rand() % (sp->exp2 - 1)) + 1;
- mpz_setbit(q, sp->exp1);
- if (sp->sign1 > 0) {
- mpz_add(r, r, q);
- } else {
- mpz_sub(r, r, q);
- }
-
- if (rand() % 2) {
- sp->sign0 = 1;
- mpz_add_ui(r, r, 1);
- } else {
- sp->sign0 = -1;
- mpz_sub_ui(r, r, 1);
- }
- if (!mpz_probab_prime_p(r, 10)) continue;
- for (i=0; i<10; i++) {
- int bit;
- //use q as a temp variable
- mpz_set_ui(q, 0);
- bit = qbits - rbits - 4 + 1;
- if (bit < 3) bit = 3;
- mpz_setbit(q, bit);
- pbc_mpz_random(h, q);
- mpz_mul_ui(h, h, 12);
- //finally q takes the value it should
- mpz_mul(q, h, r);
- mpz_sub_ui(q, q, 1);
- if (mpz_probab_prime_p(q, 10)) {
- found = 1;
- break;
- }
- }
- } while (!found);
-}
-
-// Type A1 pairings:
-
-struct a1_param_s {
- mpz_t p;
- mpz_t n;
- int l;
-};
-typedef struct a1_param_s a1_param_t[1];
-typedef struct a1_param_s *a1_param_ptr;
-
-struct a1_pairing_data_s {
- field_t Fp, Fp2, Ep;
-};
-typedef struct a1_pairing_data_s a1_pairing_data_t[1];
-typedef struct a1_pairing_data_s *a1_pairing_data_ptr;
-
-static void a1_clear(void *data) {
- a1_param_ptr param = data;
- mpz_clear(param->p);
- mpz_clear(param->n);
- pbc_free(data);
-}
-
-static void a1_out_str(FILE *stream, void *data) {
- a1_param_ptr p = data;
- param_out_type(stream, "a1");
- param_out_mpz(stream, "p", p->p);
- param_out_mpz(stream, "n", p->n);
- param_out_int(stream, "l", p->l);
-}
-
-struct pp2_coeff_s {
- element_t cx2;
- element_t cy2;
- element_t cxy;
- element_t cx;
- element_t cy;
- element_t c;
-};
-typedef struct pp2_coeff_s pp2_coeff_t[1];
-typedef struct pp2_coeff_s *pp2_coeff_ptr;
-
-static void pp2_coeff_set(pp2_coeff_ptr p,
- element_t cx2, element_t cy2, element_t cxy,
- element_t cx, element_t cy, element_t c) {
- element_init(p->cx2, cx2->field);
- element_init(p->cy2, cy2->field);
- element_init(p->cxy, cxy->field);
- element_init(p->cx, cx->field);
- element_init(p->cy, cy->field);
- element_init(p->c, c->field);
- element_set(p->cx2, cx2);
- element_set(p->cy2, cy2);
- element_set(p->cxy, cxy);
- element_set(p->cx, cx);
- element_set(p->cy, cy);
- element_set(p->c, c);
-}
-
-static void a1_pairing_pp_clear(pairing_pp_t p) {
- void **pp = p->data;
- while (*pp) {
- pbc_free(*pp);
- pp++;
- }
- pbc_free(p->data);
-}
-
-static void a1_pairing_pp_init(pairing_pp_t p, element_ptr in1, pairing_t pairing) {
- int m;
- element_ptr Px = curve_x_coord(in1);
- element_ptr Py = curve_y_coord(in1);
- a1_pairing_data_ptr a1info = pairing->data;
- p->data = pbc_malloc(sizeof(void *) * mpz_sizeinbase(pairing->r, 2));
- void **pp = p->data;
- element_t V;
- element_t a, b, c;
- element_t a2, b2, c2;
- element_t e0, e1, e2;
- element_ptr Vx, Vy;
-
- #define do_tangent() compute_abc_tangent(a, b, c, Vx, Vy, e0);
-
- #define do_line() compute_abc_line(a2, b2, c2, Vx, Vy, Px, Py, e0);
-
- element_init(V, a1info->Ep);
- element_set(V, in1);
- Vx = curve_x_coord(V);
- Vy = curve_y_coord(V);
-
- element_init(a, a1info->Fp);
- element_init(b, a1info->Fp);
- element_init(c, a1info->Fp);
- element_init(e0, a1info->Fp);
- element_init(e1, a1info->Fp);
- element_init(e2, a1info->Fp);
- element_init(a2, a1info->Fp);
- element_init(b2, a1info->Fp);
- element_init(c2, a1info->Fp);
-
- m = mpz_sizeinbase(pairing->r, 2) - 2;
-
- for(;;) {
- do_tangent();
- if (!m) break;
- element_double(V, V);
-
- if (mpz_tstbit(pairing->r, m)) {
- do_line();
- element_add(V, V, in1);
- //preprocess two at once
- //e0 = coeff of x
- element_mul(e0, a, c2);
- element_mul(e1, a2, c);
- element_add(e0, e0, e1);
-
- //e1 = coeff of y
- element_mul(e1, b2, c);
- element_mul(e2, b, c2);
- element_add(e1, e1, e2);
-
- //c = constant term
- element_mul(c, c, c2);
-
- //c2 = coeff of xy
- element_mul(c2, a, b2);
- element_mul(e2, a2, b);
- element_add(c2, c2, e2);
-
- //a = coeff of x^2
- element_mul(a, a, a2);
-
- //b = coeff of y^2
- element_mul(b, b, b2);
-
- *pp = pbc_malloc(sizeof(pp2_coeff_t));
- pp2_coeff_set(*pp, a, b, c2, e0, e1, c);
- } else {
- *pp = pbc_malloc(sizeof(pp_coeff_t));
- pp_coeff_set(*pp, a, b, c);
- }
- pp++;
- m--;
- }
- *pp = pbc_malloc(sizeof(pp_coeff_t));
- pp_coeff_set(*pp, a, b, c);
- pp++;
- *pp = NULL;
-
- element_clear(a2);
- element_clear(b2);
- element_clear(c2);
- element_clear(e2);
- element_clear(e1);
- element_clear(e0);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(V);
- #undef do_tangent
- #undef do_line
-}
-
-static void a1_pairing_pp_apply(element_ptr out, element_ptr in2, pairing_pp_t p) {
- void **pp = p->data;
- a1_pairing_data_ptr a1info = p->pairing->data;
- element_t f, f0;
- element_t e0, e1;
- int m;
- element_ptr Qx = curve_x_coord(in2);
- element_ptr Qy = curve_y_coord(in2);
- element_t Qx2, Qy2, Qxy;
-
- #define do_tangent() \
- pp_coeff_ptr ppp = *pp; \
- a_miller_evalfn(f0, ppp->a, ppp->b, ppp->c, Qx, Qy);
-
- #define do_line() { \
- pp2_coeff_ptr ppp = *pp; \
- /*we'll map Q via (x,y) --> (-x, iy) */ \
- /*hence Qx^2 = x^2, Qy^2 = -y^2, Qx Qy = -ixy */\
- /*where x = Q'x, y = Q'y */ \
- \
- /* Re = cx2 x^2 - cy2 y^2 - cx x + c */ \
- /* Im = -cxy xy + cy y */ \
- element_mul(e0, ppp->cx2, Qx2); \
- element_mul(e1, ppp->cy2, Qy2); \
- element_sub(e0, e0, e1); \
- element_mul(e1, ppp->cx, Qx); \
- element_sub(e0, e0, e1); \
- element_add(element_x(f0), e0, ppp->c); \
- \
- element_mul(e0, ppp->cy, Qy); \
- element_mul(e1, ppp->cxy, Qxy); \
- element_sub(element_y(f0), e0, e1); \
- }
-
- element_init(f, out->field);
- element_init(f0, out->field);
-
- element_set1(f);
-
- element_init(e0, a1info->Fp);
- element_init(e1, a1info->Fp);
- element_init(Qx2, a1info->Fp);
- element_init(Qy2, a1info->Fp);
- element_init(Qxy, a1info->Fp);
-
- element_square(Qx2, Qx);
- element_square(Qy2, Qy);
- element_mul(Qxy, Qx, Qy);
-
- m = mpz_sizeinbase(p->pairing->r, 2) - 2;
-
- while (m > 0) {
- if (mpz_tstbit(p->pairing->r, m)) {
- do_line();
- } else {
- do_tangent();
- }
- element_mul(f, f, f0);
- pp++;
- m--;
- element_square(f, f);
- }
- do_tangent();
- element_mul(f, f, f0);
-
- //Tate exponentiation
- //simpler but slower:
- //element_pow_mpz(out, f, p->tateexp);
- //use this trick instead:
- element_invert(f0, f);
- element_neg(element_y(f), element_y(f));
- element_mul(f, f, f0);
- element_pow_mpz(out, f, p->pairing->phikonr);
-
- /* We could use this instead but p->h is small so this does not help much
- a_tateexp(out, f, f0, p->h);
- */
-
- element_clear(Qx2);
- element_clear(Qy2);
- element_clear(Qxy);
- element_clear(f);
- element_clear(f0);
- element_clear(e1);
- element_clear(e0);
- #undef do_tangent
- #undef do_line
-}
-
-// e0 is a temp var.
-// Mixed coordinates.
-static void compute_abc_line_proj(element_ptr a, element_ptr b, element_ptr c,
- element_ptr Vx, element_ptr Vy, element_ptr z, element_ptr z2,
- element_ptr V1x, element_ptr V1y, element_ptr e0) {
- //temporally used to store Z1^3
- element_mul(c,z,z2);
- //a = Y1-Y2*Z1^3
- element_mul(e0,V1y,c);
- element_sub(a,Vy,e0);
- //b = -(X1*Z1-X2*Z1^3)
- element_mul(b,c,V1x);
- element_mul(e0,Vx,z);
- element_sub(b,b,e0);
- //c = -(Y2*b+X2*a)
- element_mul(c,b,V1y);
- element_mul(e0,a,V1x);
- element_add(c,c,e0);
- element_neg(c,c);
-}
-
-// in1, in2 are from E(F_q), out from F_q^2
-static void a1_pairing_proj(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- a1_pairing_data_ptr p = pairing->data;
- element_t V;
- element_t z, z2;
- element_t f, f0;
- element_t a, b, c;
- element_t e0;
- const element_ptr e1 = a, e2 = b, e3 = c; // used in point_to_affine() etc.
- int m;
- element_ptr Px = curve_x_coord(in1);
- element_ptr Py = curve_y_coord(in1);
- element_ptr Qx = curve_x_coord(in2);
- element_ptr Qy = curve_y_coord(in2);
- element_ptr Vx;
- element_ptr Vy;
-
- #define point_to_affine() \
- element_invert(z, z); \
- element_square(e0, z); \
- element_mul(Vx, Vx, e0); \
- element_mul(e0, e0, z); \
- element_mul(Vy, Vy, e0); \
- element_set1(z); \
- element_set1(z2);
-
- //TODO: do I need to check if V=-in1?
- //Where V=(Vx,Vy,z) and in1=(Px,Py,1), a mixed coordinates.
- #define proj_add() { \
- /* H=X2*Z1^2-X1 */ \
- element_mul(e0,Px,z2); \
- element_sub(e0,e0,Vx); \
- /* H^2 */ \
- element_square(e1,e0); \
- /* r=Y2*Z1^3-Y1 */ \
- element_mul(e2,z,z2); \
- element_mul(e2,e2,Py); \
- element_sub(e2,e2,Vy); \
- \
- /* X3=r^2-H^3-2X1*H^2 */ \
- element_set(z2,Vx); /* use z2 to store X1 and update Vx=X3 */ \
- element_square(Vx,e2); \
- element_mul(e3,e0,e1); /* e3=H^3 */ \
- element_sub(Vx,Vx,e3); \
- element_double(e3,z2); \
- element_mul(e3,e3,e1); /* 2X1*H^2 */ \
- element_sub(Vx,Vx,e3); \
- /* Y3=r(X1*H^2-X3)-Y1*H^3 */ \
- element_mul(e3,z2,e1); \
- element_sub(e3,e3,Vx); \
- element_mul(e3,e3,e2); \
- element_mul(e2,e0,e1); /* e2 no longer used. */ \
- element_mul(e2,e2,Vy); \
- element_sub(Vy,e3,e2); \
- /* Z3=Z1*H */ \
- element_mul(z,z,e0); \
- element_square(z2,z); \
- }
-
- #define proj_double() { \
- /* e0 = 3x^2 + (cc->a) z^4 */ \
- /* for this case a = 1 */ \
- element_square(e0, Vx); \
- /* element_mul_si(e0, e0, 3); */ \
- element_double(e1, e0); \
- element_add(e0, e1, e0); \
- element_square(e1, z2); \
- element_add(e0, e0, e1); \
- \
- /* z_out = 2 y z */ \
- element_mul(z, Vy, z); \
- /* element_mul_si(z, z, 2); */ \
- element_double(z, z); \
- element_square(z2, z); \
- \
- /* e1 = 4 x y^2 */ \
- element_square(e2, Vy); \
- element_mul(e1, Vx, e2); \
- /* element_mul_si(e1, e1, 4); */ \
- element_double(e1, e1); \
- element_double(e1, e1); \
- \
- /* x_out = e0^2 - 2 e1 */ \
- element_double(e3, e1); \
- element_square(Vx, e0); \
- element_sub(Vx, Vx, 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, Vx); \
- element_mul(e0, e0, e1); \
- element_sub(Vy, e0, e2); \
- }
-
- #define do_tangent() { \
- compute_abc_tangent_proj(a, b, c, Vx, Vy, z, z2, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- }
-
- #define do_line() { \
- compute_abc_line_proj(a, b, c, Vx, Vy, z, z2, Px, Py, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- }
-
- element_init(V, p->Ep);
- element_set(V, in1);
- Vx = curve_x_coord(V);
- Vy = curve_y_coord(V);
-
- element_init(f, p->Fp2);
- element_init(f0, p->Fp2);
- element_set1(f);
- element_init(a, p->Fp);
- element_init(b, p->Fp);
- element_init(c, p->Fp);
- element_init(e0, p->Fp);
- element_init(z, p->Fp);
- element_init(z2, p->Fp);
- element_set1(z);
- element_set1(z2);
-
- m = mpz_sizeinbase(pairing->r, 2) - 2;
- //TODO: sliding NAF
- for(;;) {
- do_tangent();
- if (!m) break;
-
- proj_double(); //V=2V
- if (mpz_tstbit(pairing->r, m)) {
- // point_to_affine();
- do_line();
- proj_add(); //V=V+in1
- }
-
- m--;
- element_square(f, f);
- }
-
- // Tate exponentiation.
- // Simpler but slower:
- // element_pow_mpz(out, f, p->tateexp);
- // Use this trick instead:
- element_invert(f0, f);
- element_neg(element_y(f), element_y(f));
- element_mul(f, f, f0);
- element_pow_mpz(out, f, pairing->phikonr);
-
- /* We could use this instead but p->h is small so this does not help much
- a_tateexp(out, f, f0, p->h);
- */
-
- element_clear(f);
- element_clear(f0);
- element_clear(z);
- element_clear(z2);
- element_clear(V);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(e0);
- #undef point_to_affine
- #undef proj_add
- #undef proj_double
- #undef do_tangent
- #undef do_line
-}
-
-//in1, in2 are from E(F_q), out from F_q^2
-static void a1_pairing(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- a1_pairing_data_ptr p = pairing->data;
- element_t V;
- element_t f, f0;
- element_t a, b, c;
- element_t e0;
- int m;
- element_ptr Px = curve_x_coord(in1);
- element_ptr Py = curve_y_coord(in1);
- element_ptr Qx = curve_x_coord(in2);
- element_ptr Qy = curve_y_coord(in2);
- element_ptr Vx;
- element_ptr Vy;
-
- #define do_tangent() { \
- compute_abc_tangent(a, b, c, Vx, Vy, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- }
-
- #define do_line() { \
- compute_abc_line(a, b, c, Vx, Vy, Px, Py, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- }
-
- element_init(V, p->Ep);
- element_set(V, in1);
- Vx = curve_x_coord(V);
- Vy = curve_y_coord(V);
-
- element_init(f, p->Fp2);
- element_init(f0, p->Fp2);
- element_set1(f);
- element_init(a, p->Fp);
- element_init(b, p->Fp);
- element_init(c, p->Fp);
- element_init(e0, p->Fp);
-
- m = mpz_sizeinbase(pairing->r, 2) - 2;
-
- //TODO: sliding NAF
- for(;;) {
- do_tangent();
- if (!m) break;
-
- element_double(V, V);
- if (mpz_tstbit(pairing->r, m)) {
- do_line();
- element_add(V, V, in1);
- }
-
- m--;
- element_square(f, f);
- }
-
- // Tate exponentiation.
- // Simpler but slower:
- // element_pow_mpz(out, f, p->tateexp);
- // Use this trick instead:
- element_invert(f0, f);
- element_neg(element_y(f), element_y(f));
- element_mul(f, f, f0);
- element_pow_mpz(out, f, pairing->phikonr);
-
- /* We could use this instead but p->h is small so this does not help much
- a_tateexp(out, f, f0, p->h);
- */
-
- element_clear(f);
- element_clear(f0);
- element_clear(V);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(e0);
- #undef do_tangent
- #undef do_line
-}
-
-//in1, in2 are from E(F_q), out from F_q^2
-void a1_pairings_affine(element_ptr out, element_t in1[], element_t in2[],
- int n_prod, pairing_t pairing) {
- a1_pairing_data_ptr p = pairing->data;
- element_t* V = pbc_malloc(sizeof(element_t)*n_prod);
- element_t f, f0;
- element_t a, b, c;
- element_t e0;
- int m, i;
- element_ptr Px, Py;
- element_ptr Qx, Qy;
- element_ptr Vx, Vy;
-
- #define do_tangents() { \
- for(i=0; i<n_prod; i++){ \
- Vx = curve_x_coord(V[i]); \
- Vy = curve_y_coord(V[i]); \
- Qx = curve_x_coord(in2[i]); \
- Qy = curve_y_coord(in2[i]); \
- compute_abc_tangent(a, b, c, Vx, Vy, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- } \
- }
-
- #define do_lines() { \
- for(i=0; i<n_prod; i++){ \
- Vx = curve_x_coord(V[i]); \
- Vy = curve_y_coord(V[i]); \
- Px = curve_x_coord(in1[i]); \
- Py = curve_y_coord(in1[i]); \
- Qx = curve_x_coord(in2[i]); \
- Qy = curve_y_coord(in2[i]); \
- compute_abc_line(a, b, c, Vx, Vy, Px, Py, e0); \
- a_miller_evalfn(f0, a, b, c, Qx, Qy); \
- element_mul(f, f, f0); \
- } \
- }
-
- for(i=0; i<n_prod; i++){
- element_init(V[i], p->Ep);
- element_set(V[i], in1[i]);
- }
- element_init(f, p->Fp2);
- element_init(f0, p->Fp2);
- element_set1(f);
- element_init(a, p->Fp);
- element_init(b, p->Fp);
- element_init(c, p->Fp);
- element_init(e0, p->Fp);
-
- m = mpz_sizeinbase(pairing->r, 2) - 2;
-
- //TODO: sliding NAF
- for(;;) {
- do_tangents();
- if (!m) break;
- element_multi_double(V, V, n_prod);
- if (mpz_tstbit(pairing->r, m)) {
- do_lines();
- element_multi_add(V, V, in1, n_prod);
- }
-
- m--;
- element_square(f, f);
- }
-
- // Tate exponentiation.
- // Simpler but slower:
- // element_pow_mpz(out, f, p->tateexp);
- // Use this trick instead:
- element_invert(f0, f);
- element_neg(element_y(f), element_y(f));
- element_mul(f, f, f0);
- element_pow_mpz(out, f, pairing->phikonr);
-
- /* We could use this instead but p->h is small so this does not help much
- a_tateexp(out, f, f0, p->h);
- */
-
- element_clear(f);
- element_clear(f0);
- for(i=0; i<n_prod; i++){
- element_clear(V[i]);
- }
- pbc_free(V);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(e0);
- #undef do_tangents
- #undef do_lines
-}
-
-static void a1_pairing_clear(pairing_t pairing) {
- field_clear(pairing->GT);
-
- a1_pairing_data_ptr p = pairing->data;
- field_clear(p->Ep);
- field_clear(p->Fp2);
- field_clear(p->Fp);
- pbc_free(p);
-
- mpz_clear(pairing->phikonr);
- mpz_clear(pairing->r);
- field_clear(pairing->Zr);
-}
-
-static void a1_pairing_option_set(pairing_t pairing, char *key, char *value) {
- if (!strcmp(key, "method")) {
- if (!strcmp(value, "miller")) {
- pairing->map = a1_pairing_proj;
- pairing->pp_init = a1_pairing_pp_init;
- pairing->pp_clear = a1_pairing_pp_clear;
- pairing->pp_apply = a1_pairing_pp_apply;
- } else if (!strcmp(value, "miller-affine")){
- pairing->map = a1_pairing;
- pairing->pp_init = a1_pairing_pp_init;
- pairing->pp_clear = a1_pairing_pp_clear;
- pairing->pp_apply = a1_pairing_pp_apply;
- } else if (!strcmp(value, "shipsey-stange")) {
- pairing->map = a_pairing_ellnet;
- pairing->pp_init = a_pairing_ellnet_pp_init;
- pairing->pp_clear = a_pairing_ellnet_pp_clear;
- pairing->pp_apply = a_pairing_ellnet_pp_apply;
- }
- }
-}
-
-static void a1_init_pairing(pairing_t pairing, void *data) {
- a1_param_ptr param = data;
- element_t a, b;
- mpz_init(pairing->r);
- mpz_set(pairing->r, param->n);
- field_init_fp(pairing->Zr, pairing->r);
-
- a1_pairing_data_ptr p;
-
- p = pairing->data = pbc_malloc(sizeof(a1_pairing_data_t));
-
- //k=2, hence phi_k(q) = q + 1, phikonr = (q+1)/r
- mpz_init(pairing->phikonr);
- mpz_set_ui(pairing->phikonr, param->l);
-
- field_init_fp(p->Fp, param->p);
- element_init(a, p->Fp);
- element_init(b, p->Fp);
- element_set1(a);
- element_set0(b);
- field_init_curve_ab(p->Ep, a, b, pairing->r, pairing->phikonr);
-
- // Turns out to be faster.
- field_curve_use_random_solvefory(p->Ep);
-
- element_clear(a);
- element_clear(b);
- field_init_fi(p->Fp2, p->Fp);
-
- pairing->finalpow = a_finalpow;
- pairing->G1 = pbc_malloc(sizeof(field_t));
- pairing->G2 = pairing->G1 = p->Ep;
- pairing_GT_init(pairing, p->Fp2);
-
- pairing->map = a1_pairing_proj; //default uses projective coordinates.
- pairing->phi = phi_identity;
- pairing->prod_pairings = a1_pairings_affine;
-
- pairing->clear_func = a1_pairing_clear;
-
- pairing->pp_init = a1_pairing_pp_init;
- pairing->pp_clear = a1_pairing_pp_clear;
- pairing->pp_apply = a1_pairing_pp_apply;
- pairing->option_set = a1_pairing_option_set;
-}
-
-static void a1_init(pbc_param_t p) {
- static pbc_param_interface_t interface = {{
- a1_clear,
- a1_init_pairing,
- a1_out_str,
- }};
- p->api = interface;
- a1_param_ptr param = p->data = pbc_malloc(sizeof(*param));
- mpz_init(param->p);
- mpz_init(param->n);
-}
-
-// Public interface:
-
-int pbc_param_init_a1(pbc_param_ptr par, struct symtab_s *tab) {
- a1_init(par);
- a1_param_ptr p = par->data;
-
- int err = 0;
- err += lookup_mpz(p->p, tab, "p");
- err += lookup_mpz(p->n, tab, "n");
- err += lookup_int(&p->l, tab, "l");
- return err;
-}
-
-void pbc_param_init_a1_gen(pbc_param_ptr par, mpz_t order) {
- a1_init(par);
- a1_param_ptr param = par->data;
- // If order is even, ideally check all even l, not just multiples of 4
- // but I don't see a good reason for having an even order.
- unsigned int l = 4;
- mpz_t n;
- mpz_ptr p = param->p;
- mpz_init(n);
- mpz_mul_ui(n, order, 4);
- mpz_sub_ui(p, n, 1);
- for (;;) {
- if (mpz_probab_prime_p(p, 20)) {
- break;
- }
- mpz_add(p, p, n);
- l += 4;
- }
- param->l = l;
- mpz_set(param->n, order);
- mpz_clear(n);
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/curve.c b/moon-abe/pbc-0.5.14/ecc/curve.c
deleted file mode 100644
index 3bc1f020..00000000
--- a/moon-abe/pbc-0.5.14/ecc/curve.c
+++ /dev/null
@@ -1,987 +0,0 @@
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h>
-#include <string.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_multiz.h"
-#include "pbc_poly.h"
-#include "pbc_curve.h"
-#include "pbc_memory.h"
-#include "pbc_random.h"
-#include "misc/darray.h"
-
-// Per-field data.
-typedef struct {
- field_ptr field; // The field where the curve is defined.
- element_t a, b; // The curve is E: Y^2 = X^3 + a X + b.
- // cofac == NULL means we're using the whole group of points.
- // otherwise we're working in the subgroup of order #E / cofac,
- // where #E is the number of points in E.
- mpz_ptr cofac;
- // A generator of E.
- element_t gen_no_cofac;
- // A generator of the subgroup.
- element_t gen;
- // A non-NULL quotient_cmp means we are working with the quotient group of
- // order #E / quotient_cmp, and the points are actually coset
- // representatives. Thus for a comparison, we must multiply by quotient_cmp
- // before comparing.
- mpz_ptr quotient_cmp;
-} *curve_data_ptr;
-
-// Per-element data. Elements of this group are points on the elliptic curve.
-typedef struct {
- int inf_flag; // inf_flag == 1 means O, the point at infinity.
- element_t x, y; // Otherwise we have the finite point (x, y).
-} *point_ptr;
-
-static void curve_init(element_ptr e) {
- curve_data_ptr cdp = e->field->data;
- point_ptr p = e->data = pbc_malloc(sizeof(*p));
- element_init(p->x, cdp->field);
- element_init(p->y, cdp->field);
- p->inf_flag = 1;
-}
-
-static void curve_clear(element_ptr e) {
- point_ptr p = e->data;
- element_clear(p->x);
- element_clear(p->y);
- pbc_free(e->data);
-}
-
-static int curve_is_valid_point(element_ptr e) {
- element_t t0, t1;
- int result;
- curve_data_ptr cdp = e->field->data;
- point_ptr p = e->data;
-
- if (p->inf_flag) return 1;
-
- element_init(t0, cdp->field);
- element_init(t1, cdp->field);
- element_square(t0, p->x);
- element_add(t0, t0, cdp->a);
- element_mul(t0, t0, p->x);
- element_add(t0, t0, cdp->b);
- element_square(t1, p->y);
- result = !element_cmp(t0, t1);
-
- element_clear(t0);
- element_clear(t1);
- return result;
-}
-
-static void curve_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);
-}
-
-static void curve_set(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_set(r->y, p->y);
-}
-
-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;
-}
-
-static void curve_double(element_ptr c, element_ptr a) {
- curve_data_ptr cdp = a->field->data;
- point_ptr r = c->data, p = a->data;
- if (p->inf_flag) {
- r->inf_flag = 1;
- return;
- }
- if (element_is0(p->y)) {
- r->inf_flag = 1;
- return;
- }
- double_no_check(r, p, cdp->a);
-}
-
-static void curve_mul(element_ptr c, element_ptr a, element_ptr b) {
- curve_data_ptr cdp = a->field->data;
- point_ptr r = c->data, p = a->data, q = b->data;
-
- if (p->inf_flag) {
- curve_set(c, b);
- return;
- }
- if (q->inf_flag) {
- curve_set(c, a);
- return;
- }
- if (!element_cmp(p->x, q->x)) {
- if (!element_cmp(p->y, q->y)) {
- if (element_is0(p->y)) {
- r->inf_flag = 1;
- return;
- } else {
- double_no_check(r, p, cdp->a);
- return;
- }
- }
- //points are inverses of each other
- r->inf_flag = 1;
- return;
- } else {
- element_t lambda, e0, e1;
-
- element_init(lambda, cdp->field);
- element_init(e0, cdp->field);
- element_init(e1, cdp->field);
-
- //lambda = (y2-y1)/(x2-x1)
- element_sub(e0, q->x, p->x);
- element_invert(e0, e0);
- element_sub(lambda, q->y, p->y);
- element_mul(lambda, lambda, e0);
- //x3 = lambda^2 - x1 - x2
- element_square(e0, lambda);
- 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, 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);
- }
-}
-
-//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 = pbc_malloc(sizeof(element_t)*n); //a big problem?
- element_t e0, e1, e2;
- point_ptr q, r;
- curve_data_ptr cdp = a[0]->field->data;
-
- q=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=a[i]->data; r=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=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=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=a[i]->data;
- r=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);
-}
-
-//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 = pbc_malloc(sizeof(element_t)*n); //a big problem?
- point_ptr p, q, r;
- element_t e0, e1, e2;
- curve_data_ptr cdp = a[0]->field->data;
-
- p = a[0]->data;
- q = 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 = a[i]->data;
- q = 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 = a[i]->data;
- q = 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 = a[i]->data;
- q = b[i]->data;
- r = 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);
-}
-
-
-static inline int point_cmp(point_ptr p, point_ptr q) {
- if (p->inf_flag || q->inf_flag) {
- return !(p->inf_flag && q->inf_flag);
- }
- return element_cmp(p->x, q->x) || element_cmp(p->y, q->y);
-}
-
-static int curve_cmp(element_ptr a, element_ptr b) {
- if (a == b) {
- return 0;
- } else {
- // If we're working with a quotient group we must account for different
- // representatives of the same coset.
- curve_data_ptr cdp = a->field->data;
- if (cdp->quotient_cmp) {
- element_t e;
- element_init_same_as(e, a);
- element_div(e, a, b);
- element_pow_mpz(e, e, cdp->quotient_cmp);
- int result = !element_is1(e);
- element_clear(e);
- return result;
- }
- return point_cmp(a->data, b->data);
- }
-}
-
-static void curve_set1(element_ptr x) {
- point_ptr p = x->data;
- p->inf_flag = 1;
-}
-
-static int curve_is1(element_ptr x) {
- point_ptr p = x->data;
- return p->inf_flag;
-}
-
-static void curve_random_no_cofac_solvefory(element_ptr a) {
- //TODO: with 0.5 probability negate y-coord
- curve_data_ptr cdp = a->field->data;
- point_ptr p = a->data;
- element_t t;
-
- element_init(t, cdp->field);
- p->inf_flag = 0;
- do {
- element_random(p->x);
- element_square(t, p->x);
- element_add(t, t, cdp->a);
- element_mul(t, t, p->x);
- element_add(t, t, cdp->b);
- } while (!element_is_sqr(t));
- element_sqrt(p->y, t);
- element_clear(t);
-}
-
-static void curve_random_solvefory(element_ptr a) {
- curve_data_ptr cdp = a->field->data;
- curve_random_no_cofac_solvefory(a);
- if (cdp->cofac) element_mul_mpz(a, a, cdp->cofac);
-}
-
-static void curve_random_pointmul(element_ptr a) {
- curve_data_ptr cdp = a->field->data;
- mpz_t x;
- mpz_init(x);
-
- pbc_mpz_random(x, a->field->order);
- element_mul_mpz(a, cdp->gen, x);
- mpz_clear(x);
-}
-
-void field_curve_use_random_solvefory(field_ptr f) {
- f->random = curve_random_solvefory;
-}
-
-void curve_set_gen_no_cofac(element_ptr a) {
- curve_data_ptr cdp = a->field->data;
- element_set(a, cdp->gen_no_cofac);
-}
-
-static int curve_sign(element_ptr e) {
- point_ptr p = e->data;
- if (p->inf_flag) return 0;
- return element_sign(p->y);
-}
-
-static void curve_from_hash(element_t a, void *data, int len) {
- element_t t, t1;
- point_ptr p = a->data;
- curve_data_ptr cdp = 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);
-}
-
-static size_t curve_out_str(FILE *stream, int base, element_ptr a) {
- point_ptr p = a->data;
- size_t result, status;
- if (p->inf_flag) {
- if (EOF == fputc('O', stream)) return 0;
- return 1;
- }
- if (EOF == fputc('[', stream)) return 0;
- result = element_out_str(stream, base, p->x);
- if (!result) return 0;
- if (EOF == fputs(", ", stream)) return 0;
- status = element_out_str(stream, base, p->y);
- if (!status) return 0;
- if (EOF == fputc(']', stream)) return 0;
- return result + status + 4;
-}
-
-static int curve_snprint(char *s, size_t n, element_ptr a) {
- point_ptr p = a->data;
- size_t result = 0, left;
- int status;
-
- #define clip_sub() { \
- result += status; \
- left = result >= n ? 0 : n - result; \
- }
-
- if (p->inf_flag) {
- status = snprintf(s, n, "O");
- if (status < 0) return status;
- return 1;
- }
-
- status = snprintf(s, n, "[");
- if (status < 0) return status;
- clip_sub();
- status = element_snprint(s + result, left, p->x);
- if (status < 0) return status;
- clip_sub();
- status = snprintf(s + result, left, ", ");
- if (status < 0) return status;
- clip_sub();
- status = element_snprint(s + result, left, p->y);
- if (status < 0) return status;
- clip_sub();
- status = snprintf(s + result, left, "]");
- if (status < 0) return status;
- return result + status;
- #undef clip_sub
-}
-
-static void curve_set_multiz(element_ptr a, multiz m) {
- if (multiz_is_z(m)) {
- if (multiz_is0(m)) {
- element_set0(a);
- return;
- }
- pbc_warn("bad multiz");
- return;
- } else {
- if (multiz_count(m) < 2) {
- pbc_warn("multiz has too few coefficients");
- return;
- }
- point_ptr p = a->data;
- p->inf_flag = 0;
- element_set_multiz(p->x, multiz_at(m, 0));
- element_set_multiz(p->y, multiz_at(m, 1));
- }
-}
-
-static int curve_set_str(element_ptr e, const char *s, int base) {
- point_ptr p = e->data;
- const char *cp = s;
- element_set0(e);
- while (*cp && isspace(*cp)) cp++;
- if (*cp == 'O') {
- return cp - s + 1;
- }
- p->inf_flag = 0;
- if (*cp != '[') return 0;
- cp++;
- cp += element_set_str(p->x, cp, base);
- while (*cp && isspace(*cp)) cp++;
- if (*cp != ',') return 0;
- cp++;
- cp += element_set_str(p->y, cp, base);
- if (*cp != ']') return 0;
-
- if (!curve_is_valid_point(e)) {
- element_set0(e);
- return 0;
- }
- return cp - s + 1;
-}
-
-static void field_clear_curve(field_t f) {
- curve_data_ptr cdp;
- cdp = f->data;
- element_clear(cdp->gen);
- element_clear(cdp->gen_no_cofac);
- if (cdp->cofac) {
- mpz_clear(cdp->cofac);
- pbc_free(cdp->cofac);
- }
- if (cdp->quotient_cmp) {
- mpz_clear(cdp->quotient_cmp);
- pbc_free(cdp->quotient_cmp);
- }
- element_clear(cdp->a);
- element_clear(cdp->b);
- pbc_free(cdp);
-}
-
-static int curve_length_in_bytes(element_ptr x) {
- point_ptr p = x->data;
- return element_length_in_bytes(p->x) + element_length_in_bytes(p->y);
-}
-
-static int curve_to_bytes(unsigned char *data, element_t e) {
- point_ptr P = e->data;
- int len;
- len = element_to_bytes(data, P->x);
- len += element_to_bytes(data + len, P->y);
- return len;
-}
-
-static int curve_from_bytes(element_t e, unsigned char *data) {
- point_ptr P = e->data;
- int len;
-
- P->inf_flag = 0;
- len = element_from_bytes(P->x, data);
- len += element_from_bytes(P->y, data + len);
- //if point does not lie on curve, set it to O
- if (!curve_is_valid_point(e)) {
- element_set0(e);
- }
- return len;
-}
-
-static void curve_out_info(FILE *out, field_t f) {
- int len;
- fprintf(out, "elliptic curve");
- if ((len = f->fixed_length_in_bytes)) {
- fprintf(out, ", bits per coord = %d", len * 8 / 2);
- } else {
- fprintf(out, "variable-length");
- }
-}
-
-static int odd_curve_is_sqr(element_ptr e) {
- UNUSED_VAR(e);
- return 1;
-}
-
-//TODO: untested
-static int even_curve_is_sqr(element_ptr e) {
- mpz_t z;
- element_t e1;
- int result;
-
- mpz_init(z);
- element_init(e1, e->field);
- mpz_sub_ui(z, e->field->order, 1);
- mpz_fdiv_q_2exp(z, z, 1);
- element_pow_mpz(e1, e, z);
- result = element_is1(e1);
-
- mpz_clear(z);
- element_clear(e1);
- return result;
-}
-
-static int curve_item_count(element_ptr e) {
- if (element_is0(e)) {
- return 0;
- }
- return 2;
-}
-
-static element_ptr curve_item(element_ptr e, int i) {
- if (element_is0(e)) return NULL;
- point_ptr P = e->data;
- switch(i) {
- case 0:
- return P->x;
- case 1:
- return P->y;
- default:
- return NULL;
- }
-}
-
-static element_ptr curve_get_x(element_ptr e) {
- point_ptr P = e->data;
- return P->x;
-}
-
-static element_ptr curve_get_y(element_ptr e) {
- point_ptr P = e->data;
- return P->y;
-}
-
-void field_init_curve_ab(field_ptr f, element_ptr a, element_ptr b, mpz_t order, mpz_t cofac) {
- /*
- if (element_is0(a)) {
- c->double_nocheck = cc_double_no_check_ais0;
- } else {
- c->double_nocheck = cc_double_no_check;
- }
- */
- curve_data_ptr cdp;
- field_init(f);
- mpz_set(f->order, order);
- cdp = f->data = pbc_malloc(sizeof(*cdp));
- cdp->field = a->field;
- element_init(cdp->a, cdp->field);
- element_init(cdp->b, cdp->field);
- element_set(cdp->a, a);
- element_set(cdp->b, b);
-
- f->init = curve_init;
- f->clear = curve_clear;
- f->neg = f->invert = curve_invert;
- f->square = f->doub = curve_double;
- f->multi_doub = multi_double;
- f->add = f->mul = curve_mul;
- f->multi_add = multi_add;
- f->mul_mpz = element_pow_mpz;
- f->cmp = curve_cmp;
- f->set0 = f->set1 = curve_set1;
- f->is0 = f->is1 = curve_is1;
- f->sign = curve_sign;
- f->set = curve_set;
- f->random = curve_random_pointmul;
- //f->random = curve_random_solvefory;
- f->from_hash = curve_from_hash;
- f->out_str = curve_out_str;
- f->snprint = curve_snprint;
- f->set_multiz = curve_set_multiz;
- f->set_str = curve_set_str;
- f->field_clear = field_clear_curve;
- if (cdp->field->fixed_length_in_bytes < 0) {
- f->length_in_bytes = curve_length_in_bytes;
- } else {
- f->fixed_length_in_bytes = 2 * cdp->field->fixed_length_in_bytes;
- }
- f->to_bytes = curve_to_bytes;
- f->from_bytes = curve_from_bytes;
- f->out_info = curve_out_info;
- f->item_count = curve_item_count;
- f->item = curve_item;
- f->get_x = curve_get_x;
- f->get_y = curve_get_y;
-
- if (mpz_odd_p(order)) {
- f->is_sqr = odd_curve_is_sqr;
- } else {
- f->is_sqr = even_curve_is_sqr;
- }
-
- element_init(cdp->gen_no_cofac, f);
- element_init(cdp->gen, f);
- curve_random_no_cofac_solvefory(cdp->gen_no_cofac);
- if (cofac) {
- cdp->cofac = pbc_malloc(sizeof(mpz_t));
- mpz_init(cdp->cofac);
- mpz_set(cdp->cofac, cofac);
- element_mul_mpz(cdp->gen, cdp->gen_no_cofac, cofac);
- } else{
- cdp->cofac = NULL;
- element_set(cdp->gen, cdp->gen_no_cofac);
- }
- cdp->quotient_cmp = NULL;
-}
-
-// Requires e to be a point on an elliptic curve.
-int element_to_bytes_compressed(unsigned char *data, element_ptr e) {
- point_ptr P = e->data;
- int len;
- len = element_to_bytes(data, P->x);
- if (element_sign(P->y) > 0) {
- data[len] = 1;
- } else {
- data[len] = 0;
- }
- len++;
- return len;
-}
-
-// Computes a point on the elliptic curve Y^2 = X^3 + a X + b given its
-// x-coordinate.
-// Requires a solution to exist.
-static void point_from_x(point_ptr p, element_t x, element_t a, element_t b) {
- element_t t;
-
- element_init(t, x->field);
- p->inf_flag = 0;
- element_square(t, x);
- element_add(t, t, a);
- element_mul(t, t, x);
- element_add(t, t, b);
- element_sqrt(p->y, t);
- element_set(p->x, x);
-
- element_clear(t);
-}
-
-void curve_from_x(element_ptr e, element_t x) {
- curve_data_ptr cdp = e->field->data;
- point_from_x(e->data, x, cdp->a, cdp->b);
-}
-
-// 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 = e->field->data;
- point_ptr P = 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;
-}
-
-int element_length_in_bytes_compressed(element_ptr e) {
- point_ptr P = e->data;
- return element_length_in_bytes(P->x) + 1;
-}
-
-// Requires e to be a point on an elliptic curve.
-int element_to_bytes_x_only(unsigned char *data, element_ptr e) {
- point_ptr P = e->data;
- int len;
- len = element_to_bytes(data, P->x);
- return len;
-}
-
-// Requires e to be a point on an elliptic curve.
-int element_from_bytes_x_only(element_ptr e, unsigned char *data) {
- curve_data_ptr cdp = e->field->data;
- point_ptr P = e->data;
- int len;
- len = element_from_bytes(P->x, data);
- point_from_x(P, P->x, cdp->a, cdp->b);
- return len;
-}
-
-int element_length_in_bytes_x_only(element_ptr e) {
- point_ptr P = e->data;
- return element_length_in_bytes(P->x);
-}
-
-inline element_ptr curve_x_coord(element_t e) {
- return ((point_ptr) e->data)->x;
-}
-
-inline element_ptr curve_y_coord(element_t e) {
- return ((point_ptr) e->data)->y;
-}
-
-inline element_ptr curve_a_coeff(element_t e) {
- return ((curve_data_ptr) e->field->data)->a;
-}
-
-inline element_ptr curve_b_coeff(element_t e) {
- return ((curve_data_ptr) e->field->data)->b;
-}
-
-inline element_ptr curve_field_a_coeff(field_t f) {
- return ((curve_data_ptr) f->data)->a;
-}
-
-inline element_ptr curve_field_b_coeff(field_t f) {
- return ((curve_data_ptr) f->data)->b;
-}
-
-void field_init_curve_ab_map(field_t cnew, field_t c,
- fieldmap map, field_ptr mapdest,
- mpz_t ordernew, mpz_t cofacnew) {
- element_t a, b;
- curve_data_ptr cdp = c->data;
-
- element_init(a, mapdest);
- element_init(b, mapdest);
-
- map(a, cdp->a);
- map(b, cdp->b);
-
- field_init_curve_ab(cnew, a, b, ordernew, cofacnew);
- element_clear(a);
- element_clear(b);
-}
-
-// Existing points are invalidated as this mangles c.
-void field_reinit_curve_twist(field_ptr c) {
- curve_data_ptr cdp = c->data;
- element_ptr nqr = field_get_nqr(cdp->field);
- element_mul(cdp->a, cdp->a, nqr);
- element_mul(cdp->a, cdp->a, nqr);
- element_mul(cdp->b, cdp->b, nqr);
- element_mul(cdp->b, cdp->b, nqr);
- element_mul(cdp->b, cdp->b, nqr);
-
- // Recompute generators.
- curve_random_no_cofac_solvefory(cdp->gen_no_cofac);
- if (cdp->cofac) {
- element_mul_mpz(cdp->gen, cdp->gen_no_cofac, cdp->cofac);
- } else{
- element_set(cdp->gen, cdp->gen_no_cofac);
- }
-}
-
-// I could generalize this for all fields, but is there any point?
-void field_curve_set_quotient_cmp(field_ptr c, mpz_t quotient_cmp) {
- curve_data_ptr cdp = c->data;
- cdp->quotient_cmp = pbc_malloc(sizeof(mpz_t));
- mpz_init(cdp->quotient_cmp);
- mpz_set(cdp->quotient_cmp, quotient_cmp);
-}
-
-// Requires j != 0, 1728.
-void field_init_curve_j(field_ptr f, element_ptr j, mpz_t order, mpz_t cofac) {
- element_t a, b;
- element_init(a, j->field);
- element_init(b, j->field);
-
- element_set_si(a, 1728);
- element_sub(a, a, j);
- element_invert(a, a);
- element_mul(a, a, j);
-
- //b = 2 j / (1728 - j)
- element_add(b, a, a);
- //a = 3 j / (1728 - j)
- element_add(a, a, b);
- field_init_curve_ab(f, a, b, order, cofac);
-
- element_clear(a);
- element_clear(b);
-}
-
-void field_init_curve_b(field_ptr f, element_ptr b, mpz_t order, mpz_t cofac) {
- element_t a;
- element_init(a, b->field);
- field_init_curve_ab(f, a, b, order, cofac);
-
- element_clear(a);
-}
-
-// Compute trace of Frobenius at q^n given trace at q.
-// See p.105 of Blake, Seroussi and Smart.
-void pbc_mpz_trace_n(mpz_t res, mpz_t q, mpz_t trace, int n) {
- int i;
- mpz_t c0, c1, c2;
- mpz_t t0;
-
- mpz_init(c0);
- mpz_init(c1);
- mpz_init(c2);
- mpz_init(t0);
- mpz_set_ui(c2, 2);
- mpz_set(c1, trace);
- for (i=2; i<=n; i++) {
- mpz_mul(c0, trace, c1);
- mpz_mul(t0, q, c2);
- mpz_sub(c0, c0, t0);
- mpz_set(c2, c1);
- mpz_set(c1, c0);
- }
- mpz_set(res, c1);
- mpz_clear(t0);
- mpz_clear(c2);
- mpz_clear(c1);
- mpz_clear(c0);
-}
-
-// Given q, t such that #E(F_q) = q - t + 1, compute #E(F_q^k).
-void pbc_mpz_curve_order_extn(mpz_t res, mpz_t q, mpz_t t, int k) {
- mpz_t z;
- mpz_t tk;
- mpz_init(z);
- mpz_init(tk);
- mpz_pow_ui(z, q, k);
- mpz_add_ui(z, z, 1);
- pbc_mpz_trace_n(tk, q, t, k);
- mpz_sub(z, z, tk);
- mpz_set(res, z);
- mpz_clear(z);
- mpz_clear(tk);
-}
-
-void curve_set_si(element_t R, long int x, long int y) {
- point_ptr p = R->data;
- element_set_si(p->x, x);
- element_set_si(p->y, y);
- p->inf_flag = 0;
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/d_param.c b/moon-abe/pbc-0.5.14/ecc/d_param.c
deleted file mode 100644
index 8b7d6ac5..00000000
--- a/moon-abe/pbc-0.5.14/ecc/d_param.c
+++ /dev/null
@@ -1,1258 +0,0 @@
-// Type D pairings, aka MNT curves.
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h>
-#include <string.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_poly.h"
-#include "pbc_hilbert.h"
-#include "pbc_fp.h"
-#include "pbc_fieldquadratic.h"
-#include "pbc_mnt.h"
-#include "pbc_curve.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_memory.h"
-#include "pbc_d_param.h"
-#include "ecc/param.h"
-
-struct d_param_s {
- mpz_t q; // curve defined over F_q
- mpz_t n; // has order n (= q - t + 1) in F_q
- mpz_t h; // h * r = n, r is prime
- mpz_t r;
- mpz_t a, b; // curve equation is y^2 = x^3 + ax + b
- int k; // embedding degree
- mpz_t nk; // order of curve over F_q^k
- mpz_t hk; // hk * r^2 = nk
- mpz_t *coeff; // coefficients of polynomial used to extend F_q by k/2
- mpz_t nqr; // a quadratic nonresidue in F_q^d that lies in F_q
-};
-
-typedef struct d_param_s d_param_t[1];
-typedef struct d_param_s *d_param_ptr;
-
-// Per-pairing data.
-typedef struct {
- field_t Fq, Fqx, Fqd, Fqk; // The fields F_q, F_q[x], F_q^d, F_q^k.
- field_t Eq, Etwist; // The curves E(F_q) and E'(F_q^d).
- // Let v be the quadratic nonresidue used to construct F_q^k from F_q^d,
- // namely Fqk = Fqd[sqrt(v)].
- element_t nqrinv, nqrinv2; // The constants v^-1 and v^-2.
- mpz_t tateexp; // The Tate exponent,
- // to standardize coset representatives.
- int k; // The embedding degree, usually 6.
- // Let x be the element used to build Fqd from Fq, i.e. Fqd = Fq[x].
- element_t xpowq, xpowq2; // x^q and x^{2q} in F_q^d.
-} *pptr;
-
-static void d_clear(void *data) {
- d_param_ptr param = data;
- int d = param->k / 2;
- int i;
- mpz_clear(param->q);
- mpz_clear(param->n);
- mpz_clear(param->h);
- mpz_clear(param->r);
- mpz_clear(param->a);
- mpz_clear(param->b);
- mpz_clear(param->nk);
- mpz_clear(param->hk);
- mpz_clear(param->nqr);
- for (i=0; i<d; i++) {
- mpz_clear(param->coeff[i]);
- }
- pbc_free(param->coeff);
- pbc_free(data);
-}
-
-static void d_out_str(FILE *stream, void *data) {
- d_param_ptr p = data;
- int d = p->k / 2;
- int i;
- char s[8];
- param_out_type(stream, "d");
- param_out_mpz(stream, "q", p->q);
- param_out_mpz(stream, "n", p->n);
- param_out_mpz(stream, "h", p->h);
- param_out_mpz(stream, "r", p->r);
- param_out_mpz(stream, "a", p->a);
- param_out_mpz(stream, "b", p->b);
- param_out_int(stream, "k", p->k);
- param_out_mpz(stream, "nk", p->nk);
- param_out_mpz(stream, "hk", p->hk);
- for (i=0; i<d; i++) {
- sprintf(s, "coeff%d", i);
- param_out_mpz(stream, s, p->coeff[i]);
- }
- param_out_mpz(stream, "nqr", p->nqr);
-}
-
-// Define l = aX + bY + c where a, b, c are in Fq.
-// Compute e0 = l(Q) specialized for the case when Q has the form
-// (Qx, Qy * sqrt(v)) where Qx, Qy are in Fqd and v is the quadratic nonresidue
-// used to construct the quadratic field extension Fqk of Fqd.
-static inline void d_miller_evalfn(element_t e0,
- element_t a, element_t b, element_t c, element_t Qx, element_t Qy) {
- element_ptr re_out = element_x(e0);
- element_ptr im_out = element_y(e0);
-
- int i;
- int d = polymod_field_degree(re_out->field);
- for (i = 0; i < d; i++) {
- element_mul(element_item(re_out, i), element_item(Qx, i), a);
- element_mul(element_item(im_out, i), element_item(Qy, i), b);
- }
- element_add(element_item(re_out, 0), element_item(re_out, 0), c);
-}
-
-// Miller's algorithm, assuming we can ignore the denominator. We can do this
-// with careful group selection when the embedding degree is even. See thesis.
-// This version uses projective coordinates, which don't seem much faster.
-static void cc_miller_no_denom_proj(element_t res, mpz_t q, element_t P,
- element_ptr Qx, element_ptr Qy) {
- int m;
- element_t v;
- element_t Z;
- element_t a, b, c;
- element_t t0, t1;
- element_ptr t2 = a, t3 = b, t4 = c;
- element_t e0;
- element_t z, z2;
- element_ptr Zx, Zy;
- const element_ptr curve_a = curve_a_coeff(P);
- const element_ptr Px = curve_x_coord(P);
- const element_ptr Py = curve_y_coord(P);
-
- #define proj_double() { \
- /* t0 = 3x^2 + (curve_a) z^4 */ \
- element_square(t0, Zx); \
- /* element_mul_si(t0, t0, 3); */ \
- element_double(t1, t0); \
- element_add(t0, t0, t1); \
- element_square(t1, z2); \
- element_mul(t1, t1, curve_a); \
- element_add(t0, t0, t1); \
- \
- /* z_out = 2 y z */ \
- element_mul(z, Zy, z); \
- /* element_mul_si(z, z, 2); */ \
- element_double(z, z); \
- element_square(z2, z); \
- \
- /* t1 = 4 x y^2 */ \
- element_square(t2, Zy); \
- element_mul(t1, Zx, t2); \
- /* element_mul_si(t1, t1, 4); */ \
- element_double(t1, t1); \
- element_double(t1, t1); \
- \
- /* x_out = t0^2 - 2 t1 */ \
- /* element_mul_si(t3, t1, 2); */ \
- element_double(t3, t1); \
- element_square(Zx, t0); \
- element_sub(Zx, Zx, t3); \
- \
- /* t2 = 8y^4 */ \
- element_square(t2, t2); \
- /* element_mul_si(t2, t2, 8); */ \
- element_double(t2, t2); \
- element_double(t2, t2); \
- element_double(t2, t2); \
- \
- /* y_out = t0(t1 - x_out) - t2 */ \
- element_sub(t1, t1, Zx); \
- element_mul(t0, t0, t1); \
- element_sub(Zy, t0, t2); \
- }
-
- #define proj_mixin() { \
- /* t2 = Px z^2 */ \
- element_mul(t2, z2, Px); \
- \
- /* t3 = Zx - t2 */ \
- element_sub(t3, Zx, t2); \
- \
- /* t0 = Py z^3 */ \
- element_mul(t0, z2, Py); \
- element_mul(t0, t0, z); \
- \
- /* t1 = Zy - t0 */ \
- element_sub(t1, Zy, t0); \
- \
- /* e7 = Zx + t2, use t2 to double for e7 */ \
- element_add(t2, Zx, t2); \
- \
- /* e8 = Zy + t0, use t0 to double for e8 */ \
- element_add(t0, Zy, t0); \
- \
- /* z = z t3 */ \
- element_mul(z, z, t3); \
- element_square(z2, z); \
- \
- /* Zx = t1^2 - e7 t3^2 */ \
- /* t3 now holds t3^3, */ \
- /* t4 holds e7 t3^2. */ \
- element_square(t4, t3); \
- element_mul(t3, t4, t3); \
- element_square(Zx, t1); \
- element_mul(t4, t2, t4); \
- element_sub(Zx, Zx, t4); \
- \
- /* t4 = e7 t3^2 - 2 Zx */ \
- element_sub(t4, t4, Zx); \
- element_sub(t4, t4, Zx); \
- \
- /* Zy = (t4 t1 - e8 t3^3)/2 */ \
- element_mul(t4, t4, t1); \
- element_mul(t0, t0, t3); \
- element_sub(t4, t4, t0); \
- element_halve(Zy, t4); \
- }
-
- #define do_tangent() { \
- /* a = -(3x^2 + cca z^4) */ \
- /* b = 2 y z^3 */ \
- /* c = -(2 y^2 + x a) */ \
- /* a = z^2 a */ \
- element_square(a, z2); \
- element_mul(a, a, curve_a); \
- element_square(b, Zx); \
- /* element_mul_si(b, b, 3); */ \
- element_double(t0, b); \
- element_add(b, b, t0); \
- element_add(a, a, b); \
- element_neg(a, a); \
- \
- element_mul(b, z, z2); \
- element_mul(b, b, Zy); \
- element_mul_si(b, b, 2); \
- \
- element_mul(c, Zx, a); \
- element_mul(a, a, z2); \
- element_square(t0, Zy); \
- element_mul_si(t0, t0, 2); \
- element_add(c, c, t0); \
- element_neg(c, c); \
- \
- d_miller_evalfn(e0, a, b, c, Qx, Qy); \
- element_mul(v, v, e0); \
- }
-
- #define do_line() { \
- /* a = -(Py z^3 - Zy) */ \
- /* b = Px z^3 - Zx z */ \
- /* c = Zx z Py - Zy Px; */ \
- \
- element_mul(t0, Zx, z); \
- element_mul(t1, z2, z); \
- \
- element_mul(a, Py, t1); \
- element_sub(a, Zy, a); \
- \
- element_mul(b, Px, t1); \
- element_sub(b, b, t0); \
- \
- element_mul(t0, t0, Py); \
- element_mul(c, Zy, Px); \
- element_sub(c, t0, c); \
- \
- d_miller_evalfn(e0, a, b, c, Qx, Qy); \
- element_mul(v, v, e0); \
- }
-
- element_init(a, Px->field);
- element_init(b, a->field);
- element_init(c, a->field);
- element_init(t0, a->field);
- element_init(t1, a->field);
- element_init(e0, res->field);
- element_init(z, a->field);
- element_init(z2, a->field);
- element_set1(z);
- element_set1(z2);
-
- element_init(v, res->field);
- element_init(Z, P->field);
-
- element_set(Z, P);
- Zx = curve_x_coord(Z);
- Zy = curve_x_coord(Z);
-
- element_set1(v);
- m = mpz_sizeinbase(q, 2) - 2;
-
- for(;;) {
- do_tangent();
- if (!m) break;
- proj_double();
- if (mpz_tstbit(q, m)) {
- do_line();
- proj_mixin();
- }
- m--;
- element_square(v, v);
- }
-
- element_set(res, v);
-
- element_clear(v);
- element_clear(Z);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(t0);
- element_clear(t1);
- element_clear(e0);
- element_clear(z);
- element_clear(z2);
- #undef proj_double
- #undef proj_mixin
- #undef do_tangent
- #undef do_line
-}
-
-// 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) {
- 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;
-
- /* 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 = mpz_sizeinbase(q, 2) - 2;
-
- 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
-}
-
-static void (*cc_miller_no_denom_fn)(element_t res, mpz_t q, element_t P,
- element_ptr Qx, element_ptr Qy);
-
-static void d_pairing_option_set(pairing_t pairing, char *key, char *value) {
- UNUSED_VAR(pairing);
- if (!strcmp(key, "method")) {
- if (!strcmp(value, "miller")) {
- cc_miller_no_denom_fn = cc_miller_no_denom_proj;
- } else if (!strcmp(value, "miller-affine")) {
- cc_miller_no_denom_fn = cc_miller_no_denom_affine;
- }
- }
-}
-
-// 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);
- int 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);
-}
-
-// 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
-}
-
-static void cc_finalpow(element_t e) {
- cc_tatepower(e->data, e->data, e->field->pairing);
-}
-
-static void cc_pairing(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- element_ptr Qbase = in2;
- element_t Qx, Qy;
- pptr p = pairing->data;
-
- element_init(Qx, p->Fqd);
- element_init(Qy, p->Fqd);
- // Twist: (x, y) --> (v^-1 x, v^-(3/2) y)
- // where v is the quadratic nonresidue used to construct the twist.
- element_mul(Qx, curve_x_coord(Qbase), p->nqrinv);
- // v^-3/2 = v^-2 * v^1/2
- element_mul(Qy, curve_y_coord(Qbase), p->nqrinv2);
- cc_miller_no_denom_fn(out, pairing->r, in1, Qx, Qy);
- cc_tatepower(out, out, pairing);
- element_clear(Qx);
- element_clear(Qy);
-}
-
-
-//do many millers at one time with affine coordinates.
-static void cc_millers_no_denom_affine(element_t res, mpz_t q, element_t P[],
- element_t Qx[], element_t Qy[], int n_prod) {
- int m, i;
- element_t v;
- element_t a, b, c;
- element_t t0;
- element_t e0;
- const element_ptr cca = curve_a_coeff(P[0]);
- element_ptr Px, Py;
- element_t* Z = pbc_malloc(sizeof(element_t)*n_prod);
- element_ptr Zx, Zy;
-
- /* TODO: when exactly is this not needed?
- void do_vertical() {
- mapbase(e0, Z->x);
- element_sub(e0, Qx, e0);
- element_mul(v, v, e0);
- }
- */
-
- #define do_tangents() { \
- /* a = -(3 Zx^2 + cc->a) */ \
- /* b = 2 * Zy */ \
- /* c = -(2 Zy^2 + a Zx); */ \
- for(i=0; i<n_prod; i++){ \
- Px = curve_x_coord(P[i]); \
- Py = curve_y_coord(P[i]); \
- Zx = curve_x_coord(Z[i]); \
- Zy = curve_y_coord(Z[i]); \
- \
- element_square(a, Zx); \
- element_mul_si(a, a, 3); \
- element_add(a, a, cca); \
- element_neg(a, a); \
- \
- element_add(b, Zy, Zy); \
- \
- element_mul(t0, b, Zy); \
- element_mul(c, a, Zx); \
- element_add(c, c, t0); \
- element_neg(c, c); \
- \
- d_miller_evalfn(e0, a, b, c, Qx[i], Qy[i]); \
- element_mul(v, v, e0); \
- } \
- }
-
- #define do_lines() { \
- /* a = -(B.y - A.y) / (B.x - A.x); */ \
- /* b = 1; */ \
- /* c = -(A.y + a * A.x); */ \
- /* but we multiply by B.x - A.x to avoid division. */ \
- for(i=0; i<n_prod; i++){ \
- Px = curve_x_coord(P[i]); \
- Py = curve_y_coord(P[i]); \
- Zx = curve_x_coord(Z[i]); \
- Zy = curve_y_coord(Z[i]); \
- \
- element_sub(b, Px, Zx); \
- element_sub(a, Zy, Py); \
- element_mul(t0, b, Zy); \
- element_mul(c, a, Zx); \
- element_add(c, c, t0); \
- element_neg(c, c); \
- \
- d_miller_evalfn(e0, a, b, c, Qx[i], Qy[i]); \
- element_mul(v, v, e0); \
- } \
- }
-
- Px= curve_x_coord(P[0]); //temporally used to initial a,b, c and etc.
- element_init(a, Px->field);
- element_init(b, a->field);
- element_init(c, a->field);
- element_init(t0, a->field);
- element_init(e0, res->field);
-
- element_init(v, res->field);
- for(i=0; i<n_prod; i++){
- element_init(Z[i], P[i]->field);
- element_set(Z[i], P[i]);
- }
-
- element_set1(v);
- m = mpz_sizeinbase(q, 2) - 2;
-
- for(;;) {
- do_tangents();
-
- if (!m) break;
- element_multi_double(Z, Z, n_prod); //Z_i=Z_i+Z_i for all i.
-
- if (mpz_tstbit(q, m)) {
- do_lines();
- element_multi_add(Z, Z, P, n_prod); //Z_i=Z_i+P_i for all i.
- }
- m--;
- element_square(v, v);
- }
-
- element_set(res, v);
-
- element_clear(v);
- for(i=0; i<n_prod; i++){
- element_clear(Z[i]);
- }
- pbc_free(Z);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(t0);
- element_clear(e0);
- #undef do_tangents
- #undef do_lines
-}
-
-
-void cc_pairings_affine(element_ptr out, element_t in1[], element_t in2[],
- int n_prod, pairing_t pairing) {
- element_ptr Qbase;
- element_t* Qx = pbc_malloc(sizeof(element_t)*n_prod);
- element_t* Qy = pbc_malloc(sizeof(element_t)*n_prod);
- pptr p = pairing->data;
- int i;
- for(i=0; i<n_prod; i++){
- element_init(Qx[i], p->Fqd);
- element_init(Qy[i], p->Fqd);
- Qbase = in2[i];
- // Twist: (x, y) --> (v^-1 x, v^-(3/2) y)
- // where v is the quadratic nonresidue used to construct the twist.
- element_mul(Qx[i], curve_x_coord(Qbase), p->nqrinv);
- // v^-3/2 = v^-2 * v^1/2
- element_mul(Qy[i], curve_y_coord(Qbase), p->nqrinv2);
- }
- cc_millers_no_denom_affine(out, pairing->r, in1, Qx, Qy, n_prod);
- cc_tatepower(out, out, pairing);
-
- for(i=0; i<n_prod; i++){
- element_clear(Qx[i]);
- element_clear(Qy[i]);
- }
- pbc_free(Qx);
- pbc_free(Qy);
-}
-
-
-static int cc_is_almost_coddh(element_ptr a, element_ptr b,
- element_ptr c, element_ptr d,
- pairing_t pairing) {
- int res = 0;
- element_t t0, t1, t2;
- element_t cx, cy;
- element_t dx, dy;
- pptr p = pairing->data;
-
- element_init(cx, p->Fqd);
- element_init(cy, p->Fqd);
- element_init(dx, p->Fqd);
- element_init(dy, p->Fqd);
-
- element_init(t0, p->Fqk);
- element_init(t1, p->Fqk);
- element_init(t2, p->Fqk);
- // Twist: (x, y) --> (v^-1 x, v^-(3/2) y)
- // where v is the quadratic nonresidue used to construct the twist.
- element_mul(cx, curve_x_coord(c), p->nqrinv);
- element_mul(dx, curve_x_coord(d), p->nqrinv);
- // v^-3/2 = v^-2 * v^1/2
- element_mul(cy, curve_y_coord(c), p->nqrinv2);
- element_mul(dy, curve_y_coord(d), p->nqrinv2);
-
- cc_miller_no_denom_fn(t0, pairing->r, a, dx, dy);
- cc_miller_no_denom_fn(t1, pairing->r, b, cx, cy);
- cc_tatepower(t0, t0, pairing);
- cc_tatepower(t1, t1, pairing);
- element_mul(t2, t0, t1);
- if (element_is1(t2)) res = 1; // We were given g, g^x, h, h^-x.
- else {
- // Cheaply check the other case.
- element_invert(t1, t1);
- element_mul(t2, t0, t1);
- if (element_is1(t2)) res = 1; // We were given g, g^x, h, h^x.
- }
- element_clear(cx);
- element_clear(cy);
- element_clear(dx);
- element_clear(dy);
- element_clear(t0);
- element_clear(t1);
- element_clear(t2);
- return res;
-}
-
-struct pp_coeff_s {
- element_t a;
- element_t b;
- element_t c;
-};
-typedef struct pp_coeff_s pp_coeff_t[1];
-typedef struct pp_coeff_s *pp_coeff_ptr;
-
-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;
- int 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 = mpz_sizeinbase(q, 2) - 2;
- 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
-}
-
-static void d_pairing_pp_clear(pairing_pp_t p) {
- // TODO: Better to store a sentinel value in p->data?
- mpz_ptr q = p->pairing->r;
- int m = mpz_sizeinbase(q, 2) + mpz_popcount(q) - 3;
- int i;
- pp_coeff_t *coeff = (pp_coeff_t *) p->data;
- pp_coeff_ptr pp;
- for (i=0; i<m; i++) {
- pp = coeff[i];
- element_clear(pp->a);
- element_clear(pp->b);
- element_clear(pp->c);
- }
- pbc_free(p->data);
-}
-
-static void d_pairing_pp_apply(element_ptr out, element_ptr in2,
- pairing_pp_t p) {
- mpz_ptr q = p->pairing->r;
- pptr info = p->pairing->data;
- int m = mpz_sizeinbase(q, 2) - 2;
- pp_coeff_t *coeff = (pp_coeff_t *) p->data;
- pp_coeff_ptr pp = coeff[0];
- element_ptr Qbase = in2;
- element_t e0;
- element_t Qx, Qy;
- element_t v;
- element_init_same_as(e0, out);
- element_init_same_as(v, out);
- element_init(Qx, info->Fqd);
- element_init(Qy, info->Fqd);
-
- // Twist: (x, y) --> (v^-1 x, v^-(3/2) y)
- // where v is the quadratic nonresidue used to construct the twist
- element_mul(Qx, curve_x_coord(Qbase), info->nqrinv);
- // v^-3/2 = v^-2 * v^1/2
- element_mul(Qy, curve_y_coord(Qbase), info->nqrinv2);
-
- element_set1(out);
- for(;;) {
- d_miller_evalfn(e0, pp->a, pp->b, pp->c, Qx, Qy);
- element_mul(out, out, e0);
- pp++;
-
- if (!m) break;
-
- if (mpz_tstbit(q, m)) {
- d_miller_evalfn(e0, pp->a, pp->b, pp->c, Qx, Qy);
- element_mul(out, out, e0);
- pp++;
- }
- m--;
- element_square(out, out);
- }
- cc_tatepower(out, out, p->pairing);
-
- element_clear(e0);
- element_clear(Qx);
- element_clear(Qy);
- element_clear(v);
-}
-
-static void d_pairing_clear(pairing_t pairing) {
- field_clear(pairing->GT);
- pptr p = pairing->data;
-
- if (p->k == 6) {
- element_clear(p->xpowq);
- element_clear(p->xpowq2);
- mpz_clear(pairing->phikonr);
- } else {
- mpz_clear(p->tateexp);
- }
-
- field_clear(p->Etwist);
- field_clear(p->Eq);
- element_clear(p->nqrinv);
- element_clear(p->nqrinv2);
- field_clear(p->Fqk);
- field_clear(p->Fqd);
- field_clear(p->Fqx);
- field_clear(p->Fq);
- field_clear(pairing->Zr);
- mpz_clear(pairing->r);
- pbc_free(p);
-}
-
-static void d_init_pairing(pairing_ptr pairing, void *data) {
- d_param_ptr param = data;
- pptr p;
- element_t a, b;
- element_t irred;
- int d = param->k / 2;
- int i;
-
- if (param->k % 2) pbc_die("k must be even");
-
- mpz_init(pairing->r);
- mpz_set(pairing->r, param->r);
- field_init_fp(pairing->Zr, pairing->r);
- pairing->map = cc_pairing;
- pairing->prod_pairings = cc_pairings_affine;
- pairing->is_almost_coddh = cc_is_almost_coddh;
-
- p = pairing->data = pbc_malloc(sizeof(*p));
- field_init_fp(p->Fq, param->q);
- element_init(a, p->Fq);
- element_init(b, p->Fq);
- element_set_mpz(a, param->a);
- element_set_mpz(b, param->b);
- field_init_curve_ab(p->Eq, a, b, pairing->r, param->h);
-
- field_init_poly(p->Fqx, p->Fq);
- element_init(irred, p->Fqx);
- poly_set_coeff1(irred, d);
- for (i = 0; i < d; i++) {
- element_set_mpz(element_item(irred, i), param->coeff[i]);
- }
-
- field_init_polymod(p->Fqd, irred);
- element_clear(irred);
-
- p->Fqd->nqr = pbc_malloc(sizeof(element_t));
- element_init(p->Fqd->nqr, p->Fqd);
- element_set_mpz(((element_t *) p->Fqd->nqr->data)[0], param->nqr);
-
- field_init_quadratic(p->Fqk, p->Fqd);
-
- // Compute constants involved in the final powering.
- if (param->k == 6) {
- mpz_ptr q = param->q;
- mpz_ptr z = pairing->phikonr;
- mpz_init(z);
- mpz_mul(z, q, q);
- mpz_sub(z, z, q);
- mpz_add_ui(z, z, 1);
- mpz_divexact(z, z, pairing->r);
-
- element_ptr e = p->xpowq;
- element_init(e, p->Fqd);
- element_set1(((element_t *) e->data)[1]);
- element_pow_mpz(e, e, q);
-
- element_init(p->xpowq2, p->Fqd);
- element_square(p->xpowq2, e);
- } else {
- mpz_init(p->tateexp);
- mpz_sub_ui(p->tateexp, p->Fqk->order, 1);
- mpz_divexact(p->tateexp, p->tateexp, pairing->r);
- }
-
- field_init_curve_ab_map(p->Etwist, p->Eq, element_field_to_polymod, p->Fqd, pairing->r, NULL);
- field_reinit_curve_twist(p->Etwist);
-
- mpz_t ndonr;
- mpz_init(ndonr);
- // ndonr temporarily holds the trace.
- mpz_sub(ndonr, param->q, param->n);
- mpz_add_ui(ndonr, ndonr, 1);
- // Negate it because we want the trace of the twist.
- mpz_neg(ndonr, ndonr);
- pbc_mpz_curve_order_extn(ndonr, param->q, ndonr, d);
- mpz_divexact(ndonr, ndonr, param->r);
- field_curve_set_quotient_cmp(p->Etwist, ndonr);
- mpz_clear(ndonr);
-
- element_init(p->nqrinv, p->Fqd);
- element_invert(p->nqrinv, field_get_nqr(p->Fqd));
- element_init(p->nqrinv2, p->Fqd);
- element_square(p->nqrinv2, p->nqrinv);
-
- pairing->G1 = p->Eq;
- pairing->G2 = p->Etwist;
-
- p->k = param->k;
- pairing_GT_init(pairing, p->Fqk);
- pairing->finalpow = cc_finalpow;
-
- // By default use affine coordinates.
- cc_miller_no_denom_fn = cc_miller_no_denom_affine;
- pairing->option_set = d_pairing_option_set;
- pairing->pp_init = d_pairing_pp_init;
- pairing->pp_clear = d_pairing_pp_clear;
- pairing->pp_apply = d_pairing_pp_apply;
-
- pairing->clear_func = d_pairing_clear;
-
- element_clear(a);
- element_clear(b);
-}
-
-// Computes a curve and sets fp to the field it is defined over using the
-// complex multiplication method, where cm holds the appropriate information
-// (e.g. discriminant, field order).
-static void compute_cm_curve(d_param_ptr param, pbc_cm_ptr cm) {
- element_t hp, root;
- field_t fp, fpx;
- field_t cc;
-
- field_init_fp(fp, cm->q);
- field_init_poly(fpx, fp);
- element_init(hp, fpx);
-
- mpz_t *coefflist;
- int n = pbc_hilbert(&coefflist, cm->D);
-
- // Temporarily set the coefficient of x^{n-1} to 1 so hp has degree n - 1,
- // allowing us to use poly_coeff().
- poly_set_coeff1(hp, n - 1);
- int i;
- for (i = 0; i < n; i++) {
- element_set_mpz(element_item(hp, i), coefflist[i]);
- }
- pbc_hilbert_free(coefflist, n);
-
- // TODO: Remove x = 0, 1728 roots.
- // TODO: What if there are no roots?
- //printf("hp ");
- //element_out_str(stdout, 0, hp);
- //printf("\n");
-
- element_init(root, fp);
- poly_findroot(root, hp);
- //printf("root = ");
- //element_out_str(stdout, 0, root);
- //printf("\n");
- element_clear(hp);
- field_clear(fpx);
-
- // The root is the j-invariant of the desired curve.
- field_init_curve_j(cc, root, cm->n, NULL);
- element_clear(root);
-
- // We may need to twist it.
- {
- // Pick a random point P and twist the curve if it has the wrong order.
- element_t P;
- element_init(P, cc);
- element_random(P);
- element_mul_mpz(P, P, cm->n);
- if (!element_is0(P)) field_reinit_curve_twist(cc);
- element_clear(P);
- }
-
- mpz_set(param->q, cm->q);
- mpz_set(param->n, cm->n);
- mpz_set(param->h, cm->h);
- mpz_set(param->r, cm->r);
- element_to_mpz(param->a, curve_field_a_coeff(cc));
- element_to_mpz(param->b, curve_field_b_coeff(cc));
- param->k = cm->k;
- {
- mpz_t z;
- mpz_init(z);
- // Compute order of curve in F_q^k.
- // n = q - t + 1 hence t = q - n + 1
- mpz_sub(z, param->q, param->n);
- mpz_add_ui(z, z, 1);
- pbc_mpz_trace_n(z, param->q, z, param->k);
- mpz_pow_ui(param->nk, param->q, param->k);
- mpz_sub_ui(z, z, 1);
- mpz_sub(param->nk, param->nk, z);
- mpz_mul(z, param->r, param->r);
- mpz_divexact(param->hk, param->nk, z);
- mpz_clear(z);
- }
- field_clear(cc);
- field_clear(fp);
-}
-
-static void d_param_init(pbc_param_ptr p) {
- static pbc_param_interface_t interface = {{
- d_clear,
- d_init_pairing,
- d_out_str,
- }};
- p->api = interface;
- d_param_ptr param = p->data = pbc_malloc(sizeof(*param));
- mpz_init(param->q);
- mpz_init(param->n);
- mpz_init(param->h);
- mpz_init(param->r);
- mpz_init(param->a);
- mpz_init(param->b);
- mpz_init(param->nk);
- mpz_init(param->hk);
- param->k = 0;
- param->coeff = NULL;
- mpz_init(param->nqr);
-}
-
-// Public interface:
-
-int pbc_param_init_d(pbc_param_ptr par, struct symtab_s *tab) {
- d_param_init(par);
- d_param_ptr p = par->data;
- char s[80];
- int i, d;
-
- int err = 0;
- err += lookup_mpz(p->q, tab, "q");
- err += lookup_mpz(p->n, tab, "n");
- err += lookup_mpz(p->h, tab, "h");
- err += lookup_mpz(p->r, tab, "r");
- err += lookup_mpz(p->a, tab, "a");
- err += lookup_mpz(p->b, tab, "b");
- err += lookup_int(&p->k, tab, "k");
- err += lookup_mpz(p->nk, tab, "nk");
- err += lookup_mpz(p->hk, tab, "hk");
- err += lookup_mpz(p->nqr, tab, "nqr");
-
- d = p->k / 2;
- p->coeff = pbc_realloc(p->coeff, sizeof(mpz_t) * d);
- for (i=0; i<d; i++) {
- sprintf(s, "coeff%d", i);
- mpz_init(p->coeff[i]);
- err += lookup_mpz(p->coeff[i], tab, s);
- }
- return err;
-}
-
-void pbc_param_init_d_gen(pbc_param_ptr p, pbc_cm_ptr cm) {
- d_param_init(p);
- d_param_ptr param = p->data;
- field_t Fq, Fqx, Fqd;
- element_t irred, nqr;
- int d = cm->k / 2;
- int i;
-
- compute_cm_curve(param, cm);
-
- field_init_fp(Fq, param->q);
- field_init_poly(Fqx, Fq);
- element_init(irred, Fqx);
- do {
- poly_random_monic(irred, d);
- } while (!poly_is_irred(irred));
- field_init_polymod(Fqd, irred);
-
- // Find a quadratic nonresidue of Fqd lying in Fq.
- element_init(nqr, Fqd);
- do {
- element_random(((element_t *) nqr->data)[0]);
- } while (element_is_sqr(nqr));
-
- param->coeff = pbc_realloc(param->coeff, sizeof(mpz_t) * d);
-
- for (i=0; i<d; i++) {
- mpz_init(param->coeff[i]);
- element_to_mpz(param->coeff[i], element_item(irred, i));
- }
- element_to_mpz(param->nqr, ((element_t *) nqr->data)[0]);
-
- element_clear(nqr);
- element_clear(irred);
-
- field_clear(Fqx);
- field_clear(Fqd);
- field_clear(Fq);
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/e_param.c b/moon-abe/pbc-0.5.14/ecc/e_param.c
deleted file mode 100644
index 53f7217c..00000000
--- a/moon-abe/pbc-0.5.14/ecc/e_param.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h> //for rand, pbc_malloc, pbc_free
-#include <string.h> //for strcmp
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_fp.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_curve.h"
-#include "pbc_random.h"
-#include "pbc_memory.h"
-#include "pbc_e_param.h"
-#include "ecc/param.h"
-
-struct e_param_s {
- mpz_t q; // Curve is defined over F_q.
- mpz_t r; // q = h r^2 + 1, r is prime.
- mpz_t h; // h is 28 times some square.
- mpz_t a, b; // Curve equation is Y^2 = X^3 + aX + b.
- int exp2;
- int exp1;
- int sign1;
- int sign0;
-};
-typedef struct e_param_s e_param_t[1];
-typedef struct e_param_s *e_param_ptr;
-
-struct e_pairing_data_s {
- field_t Fq, Eq;
- int exp2, exp1;
- int sign1, sign0;
- element_t R;
-};
-typedef struct e_pairing_data_s e_pairing_data_t[1];
-typedef struct e_pairing_data_s *e_pairing_data_ptr;
-
-static void e_clear(void *data) {
- e_param_ptr ep = data;
- mpz_clear(ep->q);
- mpz_clear(ep->r);
- mpz_clear(ep->h);
- mpz_clear(ep->a);
- mpz_clear(ep->b);
- pbc_free(data);
-}
-
-static void e_out_str(FILE *stream, void *data) {
- e_param_ptr p = data;
- param_out_type(stream, "e");
- param_out_mpz(stream, "q", p->q);
- param_out_mpz(stream, "r", p->r);
- param_out_mpz(stream, "h", p->h);
- param_out_mpz(stream, "a", p->a);
- param_out_mpz(stream, "b", p->b);
- param_out_int(stream, "exp2", p->exp2);
- param_out_int(stream, "exp1", p->exp1);
- param_out_int(stream, "sign1", p->sign1);
- param_out_int(stream, "sign0", p->sign0);
-}
-
-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
-}
-
-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
-}
-
-static void (*e_miller_fn)(element_t res, element_t P,
- element_ptr QR, element_ptr R,
- e_pairing_data_ptr p);
-
-static void e_pairing(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- e_pairing_data_ptr p = pairing->data;
- element_ptr Q = in2;
- element_t QR;
- element_init(QR, p->Eq);
- element_add(QR, Q, p->R);
- e_miller_fn(out, in1, QR, p->R, p);
- element_pow_mpz(out, out, pairing->phikonr);
- element_clear(QR);
-}
-
-// 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);
-}
-
-static void phi_identity(element_ptr out, element_ptr in, pairing_ptr pairing) {
- (void) pairing;
- element_set(out, in);
-}
-
-static void e_pairing_option_set(pairing_t pairing, char *key, char *value) {
- //TODO: this affects every type E pairing!
- UNUSED_VAR(pairing);
- if (!strcmp(key, "method")) {
- if (!strcmp(value, "miller")) {
- pairing->map = e_pairing;
- e_miller_fn = e_miller_proj;
- } else if (!strcmp(value, "miller-affine")) {
- pairing->map = e_pairing;
- e_miller_fn = e_miller_affine;
- } else if (!strcmp(value, "shipsey-stange")) {
- pairing->map = e_pairing_ellnet;
- }
- }
-}
-
-static void e_pairing_clear(pairing_t pairing) {
- field_clear(pairing->GT);
- e_pairing_data_ptr p = pairing->data;
- field_clear(p->Fq);
- field_clear(p->Eq);
- element_clear(p->R);
- pbc_free(p);
-
- mpz_clear(pairing->phikonr);
- mpz_clear(pairing->r);
- field_clear(pairing->Zr);
-}
-
-static void e_finalpow(element_ptr e) {
- element_pow_mpz(e->data, e->data, e->field->pairing->phikonr);
-}
-
-static void e_init_pairing(pairing_t pairing, void *data) {
- e_param_ptr param = data;
- e_pairing_data_ptr p;
- element_t a, b;
-
- mpz_init(pairing->r);
- mpz_set(pairing->r, param->r);
- field_init_fp(pairing->Zr, pairing->r);
- pairing->map = e_pairing;
- e_miller_fn = e_miller_proj;
-
- p = pairing->data = pbc_malloc(sizeof(e_pairing_data_t));
- p->exp2 = param->exp2;
- p->exp1 = param->exp1;
- p->sign1 = param->sign1;
- p->sign0 = param->sign0;
- field_init_fp(p->Fq, param->q);
- element_init(a, p->Fq);
- element_init(b, p->Fq);
- element_set_mpz(a, param->a);
- element_set_mpz(b, param->b);
- field_init_curve_ab(p->Eq, a, b, pairing->r, param->h);
-
- //k=1, hence phikonr = (p-1)/r
- mpz_init(pairing->phikonr);
- mpz_sub_ui(pairing->phikonr, p->Fq->order, 1);
- mpz_divexact(pairing->phikonr, pairing->phikonr, pairing->r);
-
- pairing->G2 = pairing->G1 = p->Eq;
- pairing_GT_init(pairing, p->Fq);
- pairing->finalpow = e_finalpow;
- pairing->phi = phi_identity;
- pairing->option_set = e_pairing_option_set;
- pairing->clear_func = e_pairing_clear;
-
- element_init(p->R, p->Eq);
- curve_set_gen_no_cofac(p->R);
-
- element_clear(a);
- element_clear(b);
-}
-
-static void e_init(pbc_param_ptr p) {
- static pbc_param_interface_t interface = {{
- e_clear,
- e_init_pairing,
- e_out_str,
- }};
- p->api = interface;
- e_param_ptr ep = p->data = pbc_malloc(sizeof(*ep));
- mpz_init(ep->q);
- mpz_init(ep->r);
- mpz_init(ep->h);
- mpz_init(ep->a);
- mpz_init(ep->b);
-}
-
-// Public interface:
-
-int pbc_param_init_e(pbc_param_ptr par, struct symtab_s *tab) {
- e_init(par);
- e_param_ptr p = par->data;
-
- int err = 0;
- err += lookup_mpz(p->q, tab, "q");
- err += lookup_mpz(p->r, tab, "r");
- err += lookup_mpz(p->h, tab, "h");
- err += lookup_mpz(p->a, tab, "a");
- err += lookup_mpz(p->b, tab, "b");
- err += lookup_int(&p->exp2, tab, "exp2");
- err += lookup_int(&p->exp1, tab, "exp1");
- err += lookup_int(&p->sign1, tab, "sign1");
- err += lookup_int(&p->sign0, tab, "sign0");
- return err;
-}
-
-void pbc_param_init_e_gen(pbc_param_t par, int rbits, int qbits) {
- e_init(par);
- e_param_ptr p = par->data;
- //3 takes 2 bits to represent
- int hbits = (qbits - 2) / 2 - rbits;
- mpz_ptr q = p->q;
- mpz_ptr r = p->r;
- mpz_ptr h = p->h;
- mpz_t n;
- field_t Fq;
- field_t cc;
- element_t j;
- int found = 0;
-
- //won't find any curves is hbits is too low
- if (hbits < 3) hbits = 3;
-
- mpz_init(n);
-
- do {
- int i;
- mpz_set_ui(r, 0);
-
- if (rand() % 2) {
- p->exp2 = rbits - 1;
- p->sign1 = 1;
- } else {
- p->exp2 = rbits;
- p->sign1 = -1;
- }
- mpz_setbit(r, p->exp2);
-
- p->exp1 = (rand() % (p->exp2 - 1)) + 1;
- //use q as a temp variable
- mpz_set_ui(q, 0);
- mpz_setbit(q, p->exp1);
-
- if (p->sign1 > 0) {
- mpz_add(r, r, q);
- } else {
- mpz_sub(r, r, q);
- }
-
- if (rand() % 2) {
- p->sign0 = 1;
- mpz_add_ui(r, r, 1);
- } else {
- p->sign0 = -1;
- mpz_sub_ui(r, r, 1);
- }
- if (!mpz_probab_prime_p(r, 10)) continue;
- for (i=0; i<10; i++) {
- //use q as a temp variable
- mpz_set_ui(q, 0);
- mpz_setbit(q, hbits + 1);
- pbc_mpz_random(h, q);
- mpz_mul(h, h, h);
- mpz_mul_ui(h, h, 3);
- //finally q takes the value it should
- mpz_mul(n, r, r);
- mpz_mul(n, n, h);
- mpz_add_ui(q, n, 1);
- if (mpz_probab_prime_p(q, 10)) {
- found = 1;
- break;
- }
- }
- } while (!found);
- /*
- do {
- mpz_set_ui(r, 0);
- mpz_setbit(r, rbits);
- pbc_mpz_random(r, r);
- mpz_nextprime(r, r);
- mpz_mul(n, r, r);
- mpz_mul_ui(n, n, 3);
- mpz_add_ui(q, n, 1);
- } while (!mpz_probab_prime_p(q, 10));
- */
-
- field_init_fp(Fq, q);
- element_init(j, Fq);
- element_set_si(j, 1);
- field_init_curve_b(cc, j, n, NULL);
- element_clear(j);
- // We may need to twist it.
- {
- // Pick a random point P and twist the curve if P has the wrong order.
- element_t P;
- element_init(P, cc);
- element_random(P);
- element_mul_mpz(P, P, n);
- if (!element_is0(P)) field_reinit_curve_twist(cc);
- element_clear(P);
- }
- element_to_mpz(p->a, curve_field_a_coeff(cc));
- element_to_mpz(p->b, curve_field_b_coeff(cc));
-
- mpz_clear(n);
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/eta_T_3.c b/moon-abe/pbc-0.5.14/ecc/eta_T_3.c
deleted file mode 100644
index 44396b76..00000000
--- a/moon-abe/pbc-0.5.14/ecc/eta_T_3.c
+++ /dev/null
@@ -1,835 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_fp.h"
-#include "pbc_memory.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_ternary_extension_field.h"
-#include "param.h"
-
-typedef struct { /* private data of $GF(3^m)$ */
- unsigned int len; /* the number of native machine integers required to represent one GF(3^m) element */
- int m; /* the irreducible polynomial is $x^m + x^t + 2$ */
- int t; /* the irreducible polynomial is $x^m + x^t + 2$ */
- element_ptr p; /* $p$ is the irreducible polynomial. */
- mpz_t n; /* group order of $G_1$, $G_2$, $G_T$ */
- mpz_t n2; /* order(elliptic curve points) / order(G_1) */
-} params;
-
-struct pairing_data {
- field_t gf3m, gf32m, gf36m;
- mpz_t n2; // cofactor
-};
-typedef struct pairing_data *pairing_data_ptr;
-
-#define PARAM(e) ((params *)e->field->data)
-#define ITEM(e,x,y) (element_item(element_item(e,x),y))
-#define print(e) {printf(#e": "); element_out_str(stdout, 10, e); printf("\n");}
-
-struct point_s { // points on the elliptic curve $y^2=x^3-x+1$
- int isinf;
- element_t x, y;
-};
-typedef struct point_s *point_ptr;
-typedef struct point_s point_t[1];
-
-#define FIELD(e) ((field_ptr) e->field)
-#define BASE(e) ((field_ptr) FIELD(e)->data)
-#define DATA(e) ((point_ptr) e->data)
-
-static void point_set(element_t e, element_t a) {
- point_ptr r = DATA(e), p = DATA(a);
- r->isinf = p->isinf;
- if (!p->isinf) {
- element_set(r->x, p->x);
- element_set(r->y, p->y);
- }
-}
-
-static void point_init(element_t e) {
- field_ptr f = BASE(e);
- e->data = pbc_malloc(sizeof(struct point_s));
- point_ptr p = DATA(e);
- element_init(p->x, f);
- element_init(p->y, f);
- p->isinf = 1;
-}
-
-static void point_clear(element_t e) {
- point_ptr p = DATA(e);
- element_clear(p->x);
- element_clear(p->y);
- pbc_free(p);
-}
-
-/* return 1 if $a!=b$, 0 otherwise. */
-static int point_cmp(element_t a, element_t b) {
- point_ptr pa = DATA(a), pb = DATA(b);
- if (pa->isinf == pb->isinf) {
- if (pa->isinf)
- return 0;
- else
- return element_cmp(pa->x, pb->x) || element_cmp(pa->y, pb->y);
- } else
- return 1;
-}
-
-static void point_set0(element_ptr e) {
- DATA(e)->isinf = 1;
-}
-
-static int point_is0(element_ptr e) {
- return DATA(e)->isinf;
-}
-
-static void point_random(element_t a) {
- point_ptr p = DATA(a);
- element_ptr x = p->x, y = p->y;
- field_ptr f = x->field;
- p->isinf = 0;
- element_t t, t2, e1;
- element_init(t, f);
- element_init(e1, f);
- element_set1(e1);
- element_init(t2, f);
- do {
- element_random(x);
- if (element_is0(x))
- continue;
- element_cubic(t, x); // t == x^3
- element_sub(t, t, x); // t == x^3 - x
- element_add(t, t, e1); // t == x^3 - x + 1
- element_sqrt(y, t); // y == sqrt(x^3 - x + 1)
- element_mul(t2, y, y); // t2 == x^3 - x + 1
- } while (element_cmp(t2, t)); // t2 != t
-
- // make sure order of $a$ is order of $G_1$
- pairing_ptr pairing = FIELD(a)->pairing;
- pairing_data_ptr dp = pairing->data;
- element_pow_mpz(a, a, dp->n2);
-
- element_clear(t);
- element_clear(t2);
- element_clear(e1);
-}
-
-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);
-}
-
-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);
- }
-}
-
-static size_t point_out_str(FILE *stream, int base, element_ptr a) {
- point_ptr p = DATA(a);
- size_t size = 0;
- if (p->isinf)
- return fprintf(stream, "O");
- else {
- size += element_out_str(stream, base, p->x);
- size += element_out_str(stream, base, p->y);
- return size;
- }
-}
-
-static void point_field_clear(field_ptr f) {
- UNUSED_VAR(f);
-}
-
-void field_init_eta_T_3(field_t f, field_t base) {
- field_init(f);
- f->data = (void *) base;
- f->init = point_init;
- f->clear = point_clear;
- f->random = point_random;
- f->set = point_set;
- f->cmp = point_cmp;
- f->invert = f->neg = point_invert;
- f->mul = f->add = point_add;
- f->set1 = f->set0 = point_set0;
- f->is1 = f->is0 = point_is0;
- f->mul_mpz = f->pow_mpz;
- f->out_str = point_out_str;
- f->field_clear = point_field_clear;
- f->name = "eta_T_3 point group";
-}
-
-/* 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);
-}
-
-static void algorithm5(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, nu, S, S2;
- 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(nu, f);
- element_init(S, f6);
- element_init(S2, 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) / 4; i++) {
- element_cubic(R, R);
- element_cubic(R, R); // R <= R^9
- 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); // yq <= yq^9
- element_add(t, xp, xq); // t == xp+xq
- element_mul(u, yp, yq); // u == yp*yq
- element_neg(nu, u); // nu == -yp*yq
- algorithm4a(S, t, nu); // S == (-t^2 -u*s -t*p -p^2)^3
- 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); // yq <= yq^9
- element_add(t, xp, xq); // t == xp+xq
- element_mul(u, yp, yq); // u == yp*yq
- element_neg(nt, t); // nt == -t
- element_mul(nt2, t, nt); // nt2 == -t^2
- // S2 = [[nt2, u], [nt, f3m.zero()], [f3m.two(), f3m.zero()]]
- // S2 == -t^2 +u*s -t*p -p^2
- element_set(ITEM(S2,0,0), nt2);
- element_set(ITEM(S2,0,1), u);
- element_set(ITEM(S2,1,0), nt);
- element_set0(ITEM(S2,1,1));
- element_neg(ITEM(S2,2,0), e1);
- element_set0(ITEM(S2,2,1));
- element_mul(S, S, S2);
- 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(nu);
- element_clear(S);
- element_clear(S2);
-}
-
-/* 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);
-}
-
-/* computation of $c <- U ^ {3^{3m} - 1}$
- * This is the algorithm 6 in the paper above. */
-static void algorithm6(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)*/
- field_t f3; /*GF(3^{3*m})*/
- field_init_gf33m(f3, f);
- element_t v0, v1, m0, m1, m2, a0, a1, i;
- element_init(v0, f3);
- element_init(v1, f3);
- element_init(m0, f3);
- element_init(m1, f3);
- element_init(m2, f3);
- element_init(a0, f3);
- element_init(a1, f3);
- element_init(i, f3);
- element_set(element_item(v0, 0), u0);
- element_set(element_item(v0, 1), u2);
- element_set(element_item(v0, 2), u4);
- element_set(element_item(v1, 0), u1);
- element_set(element_item(v1, 1), u3);
- element_set(element_item(v1, 2), u5);
- element_mul(m0, v0, v0);
- element_mul(m1, v1, v1);
- element_mul(m2, v0, v1);
- element_sub(a0, m0, m1);
- element_add(a1, m0, m1);
- element_invert(i, a1);
- element_mul(v0, a0, i);
- element_mul(v1, m2, i);
- element_set(ITEM(c,0,0), element_item(v0, 0));
- element_set(ITEM(c,1,0), element_item(v0, 1));
- element_set(ITEM(c,2,0), element_item(v0, 2));
- element_set(ITEM(c,0,1), element_item(v1, 0));
- element_set(ITEM(c,1,1), element_item(v1, 1));
- element_set(ITEM(c,2,1), element_item(v1, 2));
- element_clear(v0);
- element_clear(v1);
- element_clear(m0);
- element_clear(m1);
- element_clear(m2);
- element_clear(a0);
- element_clear(a1);
- element_clear(i);
- field_clear(f3);
-}
-
-/* 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);
-}
-
-/* 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);
-}
-
-/* computing the Eta_T bilinear pairing $c <- Eta_T pairing(P,R)$ */
-static void eta_T_pairing(element_ptr c, element_ptr P, element_ptr R, struct pairing_s *p) {
- UNUSED_VAR(p);
- if (DATA(P)->isinf || DATA(R)->isinf)
- element_set1(c);
- else {
- element_ptr x1 = DATA(P)->x, y1 = DATA(P)->y, x2 = DATA(R)->x, y2 =
- DATA(R)->y;
- if((PARAM(x1)->m - 1) / 2 % 2 == 0)
- algorithm5(c, x1, y1, x2, y2);
- else
- algorithm4(c, x1, y1, x2, y2);
- algorithm8(c, c);
- }
-}
-
-static void eta_T_3_clear(params *p) {
- mpz_clear(p->n);
- mpz_clear(p->n2);
- pbc_free(p);
-}
-
-static void GT_random(element_ptr e) {
- element_t a, b;
- element_init(a, e->field->pairing->G1);
- element_init(b, e->field->pairing->G1);
- element_random(a);
- element_random(b);
- element_pairing(e, a, b);
- element_clear(a);
- element_clear(b);
-}
-
-static void eta_T_3_pairing_clear(pairing_t pairing) {
- mpz_clear(pairing->r);
- field_clear(pairing->Zr);
- field_clear(pairing->GT);
- field_clear(pairing->G1);
- pbc_free(pairing->G1);
- pairing_data_ptr dp = pairing->data;
- field_clear(dp->gf3m);
- field_clear(dp->gf32m);
- field_clear(dp->gf36m);
- mpz_clear(dp->n2);
- pbc_free(dp);
-}
-
-static void eta_T_3_init_pairing(pairing_t pairing, params *p) {
- mpz_init(pairing->r);
- mpz_set(pairing->r, p->n);
- field_init_fp(pairing->Zr, pairing->r);
-
- pairing_data_ptr dp = pbc_malloc(sizeof(*dp));
- mpz_init(dp->n2);
- mpz_set(dp->n2, p->n2);
- field_init_gf3m(dp->gf3m, p->m, p->t);
- field_init_gf32m(dp->gf32m, dp->gf3m);
- field_init_gf33m(dp->gf36m, dp->gf32m);
- pairing_GT_init(pairing, dp->gf36m);
- pairing->GT->name = "eta_T_3 group of roots of 1";
- pairing->GT->random = GT_random;
- pairing->G2 = pairing->G1 = pbc_malloc(sizeof(field_t));
- field_init_eta_T_3(pairing->G1, dp->gf3m);
- pairing->G1->pairing = pairing;
- mpz_set(pairing->G1->order, p->n);
- mpz_set(pairing->GT->order, p->n);
- pairing->map = eta_T_pairing;
- pairing->data = dp;
- pairing->clear_func = eta_T_3_pairing_clear;
-}
-
-static void eta_T_3_out_str(FILE *stream, params *p) {
- param_out_type(stream, "i");
- param_out_int(stream, "m", p->m);
- param_out_int(stream, "t", p->t);
- param_out_mpz(stream, "n", p->n);
- param_out_mpz(stream, "n2", p->n2);
-}
-
-static void param_init(pbc_param_ptr p) {
- static pbc_param_interface_t interface = {{
- (void (*)(void *))eta_T_3_clear,
- (void (*)(pairing_t, void *))eta_T_3_init_pairing,
- (void (*)(FILE *, void *))eta_T_3_out_str,
- }};
- p->api = interface;
- params *param = p->data = pbc_malloc(sizeof(*param));
- mpz_init(param->n);
- mpz_init(param->n2);
-}
-
-int pbc_param_init_i(pbc_param_ptr p, struct symtab_s *tab) {
- param_init(p);
- params *param = p->data;
- int err = 0;
- err += lookup_int(&param->m, tab, "m");
- err += lookup_int(&param->t, tab, "t");
- err += lookup_mpz(param->n, tab, "n");
- err += lookup_mpz(param->n2, tab, "n2");
- return err;
-}
-
-void pbc_param_init_i_gen(pbc_param_ptr par, int group_size) {
- param_init(par);
- params *p = par->data;
- if (group_size <= 150) {
- p->m = 97;
- p->t = 12;
- mpz_set_str(p->n, "2726865189058261010774960798134976187171462721", 10);
- mpz_set_str(p->n2, "7", 10);
- } else if (group_size <= 206) {
- p->m = 199;
- p->t = 164;
- mpz_set_str(p->n, "167725321489096000055336949742738378351010268990525380470313869", 10);
- mpz_set_str(p->n2, "527874953560391326545598291952743", 10);
- } else if (group_size <= 259) {
- p->m = 235;
- p->t = 26;
- mpz_set_str(p->n, "1124316700897695330265827797088699345032488681307846555184025129863722718180241", 10);
- mpz_set_str(p->n2, "11819693021332914275777073321995059", 10);
- } else if (group_size <= 316) {
- p->m = 385;
- p->t = 22;
- mpz_set_str(p->n, "140884762419712839999909157778648717913595360839856026704744558309545986970238264714753014287541", 10);
- mpz_set_str(p->n2, "34899486997246711147841377458771182755186809219564106252058066150110543296498189654810187", 10);
- } else if (group_size <= 376) {
- p->m = 337;
- p->t = 30;
- mpz_set_str(p->n, "250796519030408069744426774377542635685621984993105288007781750196791322190409525696108840742205849171229571431053", 10);
- mpz_set_str(p->n2, "245777055088325363697128811262733732423405120899", 10);
- } else if (group_size <= 430) {
- p->m = 373;
- p->t = 198;
- mpz_set_str(p->n, "2840685307599487500956683789051368080919805957805957356540760731597378326586402072132959867084691357708217739285576524329854284197", 10);
- mpz_set_str(p->n2, "3256903458766749542151641063558247849550904613763", 10);
- } else if (group_size <= 484) {
- p->m = 395;
- p->t = 338;
- mpz_set_str(p->n, "80172097064154181257340545445945701478615643539554910656655431171167598268341527430200810544156625333601812351266052856520678455274751591367269291", 10);
- mpz_set_str(p->n2, "3621365590261279902324876775553649595261567", 10);
- } else if (group_size <= 552) {
- p->m = 433;
- p->t = 120;
- mpz_set_str(p->n, "15699907553631673835088720676147779193076555382157913339177784853763686462870506492752576492212322736133645158157557950634628006965882177348385366381692092784577773463", 10);
- mpz_set_str(p->n2, "24980791723059119877470531054938874784049", 10);
- } else if (group_size <= 644) {
- p->m = 467;
- p->t = 48;
- mpz_set_str(p->n, "108220469499363631995525712756135494735252733492048868417164002000654321383482753640072319529019505742300964525569770933946381504691909098938045089999753901375631613294579329433690943459352138231", 10);
- mpz_set_str(p->n2, "60438898450096967424971813347", 10);
- } else if (group_size <= 696) {
- p->m = 503;
- p->t = 104;
- mpz_set_str(p->n, "545523657676112447260904563578912738373307867219686215849632469801471112426878939776725222290437653718473962733760874627315930933126581248465899651120481066111839081575164964589811985885719017214938514563804313", 10);
- mpz_set_str(p->n2, "1799606423432800810122901025413", 10);
- } else if (group_size <= 803) {
- p->m = 509;
- p->t = 358;
- mpz_set_str(p->n, "102239946202586852409809887418093021457150612495255706614733003327526279081563687830782748305746187060264985869283524441819589592750998086186315250781067131293823177124077445718802216415539934838376431091001197641295264650596195201747790167311", 10);
- mpz_set_str(p->n2, "7", 10);
- } else if (group_size <= 892) {
- p->m = 617;
- p->t = 88;
- mpz_set_str(p->n, "57591959284219511220590893724691916802833742568034971006633345422620650391172287893878655658086794200963521584019889327992536532560877385225451713282279597074750857647455565899702728629166541223955196002755787520206774906606158388947359746178875040401304783332742806641", 10);
- mpz_set_str(p->n2, "42019638181715250622338241", 10);
- } else
- pbc_die("unsupported group size");
-}
-
diff --git a/moon-abe/pbc-0.5.14/ecc/f_param.c b/moon-abe/pbc-0.5.14/ecc/f_param.c
deleted file mode 100644
index 2477ace1..00000000
--- a/moon-abe/pbc-0.5.14/ecc/f_param.c
+++ /dev/null
@@ -1,599 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_fp.h"
-#include "pbc_fieldquadratic.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_poly.h"
-#include "pbc_curve.h"
-#include "pbc_memory.h"
-#include "pbc_f_param.h"
-#include "ecc/param.h"
-
-struct f_param_s {
- mpz_t q; // Curve defined over F_q.
- mpz_t r; // The order of the curve.
- mpz_t b; // E: y^2 = x^3 + b
- mpz_t beta; //beta is a quadratic nonresidue in Fq
- //we use F_q^2 = F_q[sqrt(beta)]
- mpz_t alpha0, alpha1;
- //the polynomial x^6 + alpha0 + alpha1 sqrt(beta)
- //is irreducible over F_q^2[x], so
- //we can extend F_q^2 to F_q^12 using the
- //sixth root of -(alpha0 + alpha1 sqrt(beta))
-};
-typedef struct f_param_s f_param_t[1];
-typedef struct f_param_s *f_param_ptr;
-
-// TODO: we never use phikonr so don't bother computing it,
-// but one day other routines might need it
-struct f_pairing_data_s {
- field_t Fq, Fq2, Fq2x, Fq12;
- field_t Eq, Etwist;
- element_t negalpha;
- element_t negalphainv;
- mpz_t tateexp;
-
- //for tate exponentiation speedup:
- //x^{q^k} for various k
- element_t xpowq2, xpowq6, xpowq8;
-};
-typedef struct f_pairing_data_s f_pairing_data_t[1];
-typedef struct f_pairing_data_s *f_pairing_data_ptr;
-
-static void f_clear(void *data) {
- f_param_ptr fp = data;
- mpz_clear(fp->q);
- mpz_clear(fp->r);
- mpz_clear(fp->b);
- mpz_clear(fp->beta);
- mpz_clear(fp->alpha0);
- mpz_clear(fp->alpha1);
- pbc_free(data);
-}
-
-static void f_out_str(FILE *stream, void *data) {
- f_param_ptr p = data;
- param_out_type(stream, "f");
- param_out_mpz(stream, "q", p->q);
- param_out_mpz(stream, "r", p->r);
- param_out_mpz(stream, "b", p->b);
- param_out_mpz(stream, "beta", p->beta);
- param_out_mpz(stream, "alpha0", p->alpha0);
- param_out_mpz(stream, "alpha1", p->alpha1);
-}
-
-static void tryminusx(mpz_ptr q, mpz_ptr x) {
- //36x4 - 36x3 + 24x2 - 6x + 1
- //= ((36(x - 1)x + 24)x - 6)x + 1
- mpz_sub_ui(q, x, 1);
- mpz_mul(q, q, x);
- mpz_mul_ui(q, q, 36);
- mpz_add_ui(q, q, 24);
- mpz_mul(q, q, x);
- mpz_sub_ui(q, q, 6);
- mpz_mul(q, q, x);
- mpz_add_ui(q, q, 1);
-}
-
-static void tryplusx(mpz_ptr q, mpz_ptr x) {
- //36x4 + 36x3 + 24x2 + 6x + 1
- //= ((36(x + 1)x + 24)x + 6)x + 1
- mpz_add_ui(q, x, 1);
- mpz_mul(q, q, x);
- mpz_mul_ui(q, q, 36);
- mpz_add_ui(q, q, 24);
- mpz_mul(q, q, x);
- mpz_add_ui(q, q, 6);
- mpz_mul(q, q, x);
- mpz_add_ui(q, q, 1);
-}
-
-static void cc_miller_no_denom(element_t res, mpz_t q, element_t P,
- element_ptr Qx, element_ptr Qy, element_t negalpha) {
- int 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 = mpz_sizeinbase(q, 2) - 2;
-
- //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
-}
-
-static void f_tateexp(element_t out) {
- element_t x, y, epow;
- f_pairing_data_ptr p = out->field->pairing->data;
- element_init(x, p->Fq12);
- element_init(y, p->Fq12);
- element_init(epow, p->Fq2);
-
- #define qpower(e1, e) { \
- element_set(element_item(e1, 0), element_item(out, 0)); \
- element_mul(element_item(e1, 1), element_item(out, 1), e); \
- element_square(epow, e); \
- element_mul(element_item(e1, 2), element_item(out, 2), epow); \
- element_mul(epow, epow, e); \
- element_mul(element_item(e1, 3), element_item(out, 3), epow); \
- element_mul(epow, epow, e); \
- element_mul(element_item(e1, 4), element_item(out, 4), epow); \
- element_mul(epow, epow, e); \
- element_mul(element_item(e1, 5), element_item(out, 5), epow); \
- }
-
- qpower(y, p->xpowq8);
- qpower(x, p->xpowq6);
- element_mul(y, y, x);
- qpower(x, p->xpowq2);
- element_mul(x, x, out);
- element_invert(x, x);
- element_mul(out, y, x);
-
- element_clear(epow);
- element_clear(x);
- element_clear(y);
- element_pow_mpz(out, out, p->tateexp);
- #undef qpower
-}
-
-static void f_finalpow(element_t out) {
- f_tateexp(out->data);
-}
-
-static void f_pairing(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- element_ptr Qbase = in2;
- element_t x, y;
- f_pairing_data_ptr p = pairing->data;
-
- element_init(x, p->Fq2);
- element_init(y, p->Fq2);
- //map from twist: (x, y) --> (v^-2 x, v^-3 y)
- //where v is the sixth root used to construct the twist
- //i.e. v^6 = -alpha
- //thus v^-2 = -alpha^-1 v^4
- //and v^-3 = -alpha^-1 v^3
- element_mul(x, curve_x_coord(Qbase), p->negalphainv);
- element_mul(y, curve_y_coord(Qbase), p->negalphainv);
-
- cc_miller_no_denom(out, pairing->r, in1, x, y, p->negalpha);
-
- element_clear(x);
- element_clear(y);
-
- f_tateexp(out);
-}
-
-static void f_pairing_clear(pairing_t pairing) {
- field_clear(pairing->GT);
- f_pairing_data_ptr p = pairing->data;
- element_clear(p->negalpha);
- element_clear(p->negalphainv);
- mpz_clear(p->tateexp);
- element_clear(p->xpowq2);
- element_clear(p->xpowq6);
- element_clear(p->xpowq8);
- field_clear(p->Etwist);
- field_clear(p->Eq);
-
- field_clear(p->Fq12);
- field_clear(p->Fq2x);
- field_clear(p->Fq2);
- field_clear(p->Fq);
- pbc_free(p);
-
- mpz_clear(pairing->r);
- field_clear(pairing->Zr);
-}
-
-static void f_init_pairing(pairing_t pairing, void *data) {
- f_param_ptr param = data;
- f_pairing_data_ptr p;
- element_t irred;
- element_t e0, e1, e2;
- p = pairing->data = pbc_malloc(sizeof(f_pairing_data_t));
- mpz_init(pairing->r);
- mpz_set(pairing->r, param->r);
- field_init_fp(pairing->Zr, pairing->r);
- field_init_fp(p->Fq, param->q);
- p->Fq->nqr = pbc_malloc(sizeof(element_t));
- element_init(p->Fq->nqr, p->Fq);
- element_set_mpz(p->Fq->nqr, param->beta);
- field_init_quadratic(p->Fq2, p->Fq);
- field_init_poly(p->Fq2x, p->Fq2);
- element_init(irred, p->Fq2x);
- // Call poly_set_coeff1() first so we can use element_item() for the other
- // coefficients.
- poly_set_coeff1(irred, 6);
-
- element_init(p->negalpha, p->Fq2);
- element_init(p->negalphainv, p->Fq2);
- element_set_mpz(element_x(p->negalpha), param->alpha0);
- element_set_mpz(element_y(p->negalpha), param->alpha1);
-
- element_set(element_item(irred, 0), p->negalpha);
- field_init_polymod(p->Fq12, irred);
- element_neg(p->negalpha, p->negalpha);
- element_invert(p->negalphainv, p->negalpha);
- element_clear(irred);
-
- element_init(e0, p->Fq);
- element_init(e1, p->Fq);
- element_init(e2, p->Fq2);
-
- // Initialize the curve Y^2 = X^3 + b.
- element_set_mpz(e1, param->b);
- field_init_curve_ab(p->Eq, e0, e1, pairing->r, NULL);
-
- // Initialize the curve Y^2 = X^3 - alpha0 b - alpha1 sqrt(beta) b.
- element_set_mpz(e0, param->alpha0);
- element_neg(e0, e0);
- element_mul(element_x(e2), e0, e1);
- element_set_mpz(e0, param->alpha1);
- element_neg(e0, e0);
- element_mul(element_y(e2), e0, e1);
- element_clear(e0);
- element_init(e0, p->Fq2);
- field_init_curve_ab(p->Etwist, e0, e2, pairing->r, NULL);
- element_clear(e0);
- element_clear(e1);
- element_clear(e2);
-
- mpz_t ndonr;
- mpz_init(ndonr);
- // ndonr temporarily holds the trace.
- mpz_sub(ndonr, param->q, param->r);
- mpz_add_ui(ndonr, ndonr, 1);
- // TODO: We can use a smaller quotient_cmp, but I have to figure out
- // BN curves again.
- pbc_mpz_curve_order_extn(ndonr, param->q, ndonr, 12);
- mpz_divexact(ndonr, ndonr, param->r);
- mpz_divexact(ndonr, ndonr, param->r);
- field_curve_set_quotient_cmp(p->Etwist, ndonr);
- mpz_clear(ndonr);
-
- pairing->G1 = p->Eq;
- pairing->G2 = p->Etwist;
- pairing_GT_init(pairing, p->Fq12);
- pairing->finalpow = f_finalpow;
- pairing->map = f_pairing;
- pairing->clear_func = f_pairing_clear;
-
- mpz_init(p->tateexp);
- /* unoptimized tate exponent
- mpz_pow_ui(p->tateexp, param->q, 12);
- mpz_sub_ui(p->tateexp, p->tateexp, 1);
- mpz_divexact(p->tateexp, p->tateexp, param->r);
- */
- mpz_ptr z = p->tateexp;
- mpz_mul(z, param->q, param->q);
- mpz_sub_ui(z, z, 1);
- mpz_mul(z, z, param->q);
- mpz_mul(z, z, param->q);
- mpz_add_ui(z, z, 1);
- mpz_divexact(z, z, param->r);
-
- element_init(p->xpowq2, p->Fq2);
- element_init(p->xpowq6, p->Fq2);
- element_init(p->xpowq8, p->Fq2);
- element_t xpowq;
- element_init(xpowq, p->Fq12);
-
- //there are smarter ways since we know q = 1 mod 6
- //and that x^6 = -alpha
- //but this is fast enough
- element_set1(element_item(xpowq, 1));
- element_pow_mpz(xpowq, xpowq, param->q);
- element_pow_mpz(xpowq, xpowq, param->q);
- element_set(p->xpowq2, element_item(xpowq, 1));
-
- element_pow_mpz(xpowq, xpowq, param->q);
- element_pow_mpz(xpowq, xpowq, param->q);
- element_pow_mpz(xpowq, xpowq, param->q);
- element_pow_mpz(xpowq, xpowq, param->q);
- element_set(p->xpowq6, element_item(xpowq, 1));
-
- element_pow_mpz(xpowq, xpowq, param->q);
- element_pow_mpz(xpowq, xpowq, param->q);
- element_set(p->xpowq8, element_item(xpowq, 1));
-
- element_clear(xpowq);
-}
-
-static void f_init(pbc_param_ptr p) {
- static pbc_param_interface_t interface = {{
- f_clear,
- f_init_pairing,
- f_out_str,
- }};
- p->api = interface;
- f_param_ptr fp = p->data = pbc_malloc(sizeof(*fp));
- mpz_init(fp->q);
- mpz_init(fp->r);
- mpz_init(fp->b);
- mpz_init(fp->beta);
- mpz_init(fp->alpha0);
- mpz_init(fp->alpha1);
-}
-
-// Public interface:
-
-int pbc_param_init_f(pbc_param_ptr par, struct symtab_s *tab) {
- f_init(par);
- f_param_ptr p = par->data;
-
- int err = 0;
- err += lookup_mpz(p->q, tab, "q");
- err += lookup_mpz(p->r, tab, "r");
- err += lookup_mpz(p->b, tab, "b");
- err += lookup_mpz(p->beta, tab, "beta");
- err += lookup_mpz(p->alpha0, tab, "alpha0");
- err += lookup_mpz(p->alpha1, tab, "alpha1");
- return err;
-}
-
-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);
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/g_param.c b/moon-abe/pbc-0.5.14/ecc/g_param.c
deleted file mode 100644
index 75a08c57..00000000
--- a/moon-abe/pbc-0.5.14/ecc/g_param.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h>
-#include <string.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_poly.h"
-#include "pbc_hilbert.h"
-#include "pbc_fp.h"
-#include "pbc_fieldquadratic.h"
-#include "pbc_mnt.h"
-#include "pbc_curve.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_memory.h"
-#include "pbc_g_param.h"
-#include "ecc/param.h"
-
-struct g_param_s {
- mpz_t q; // Curve defined over F_q.
- mpz_t n; // n = #E(F_q) (= q - t + 1)
- mpz_t h; // h * r = n, r is prime
- mpz_t r;
- mpz_t a, b; // E: y^2 = x^3 + ax + b
-
- // k = 10 for these curves.
- mpz_t nk; // #E(F_q^k)
- mpz_t hk; // hk * r^2 = nk
- mpz_t *coeff; //Coefficients of polynomial used to extend F_q by k/2
- mpz_t nqr; // Quadratic nonresidue in F_q^d that lies in F_q.
-};
-
-typedef struct g_param_s g_param_t[1];
-typedef struct g_param_s *g_param_ptr;
-
-struct mnt_pairing_data_s {
- field_t Fq, Fqx, Fqd, Fqk;
- field_t Eq, Etwist;
- element_t nqrinv, nqrinv2;
- element_t xpowq, xpowq2, xpowq3, xpowq4;
-};
-typedef struct mnt_pairing_data_s mnt_pairing_data_t[1];
-typedef struct mnt_pairing_data_s *mnt_pairing_data_ptr;
-
-static void g_clear(void *data) {
- g_param_ptr param = data;
- int i;
- mpz_clear(param->q);
- mpz_clear(param->n);
- mpz_clear(param->h);
- mpz_clear(param->r);
- mpz_clear(param->a);
- mpz_clear(param->b);
- mpz_clear(param->nk);
- mpz_clear(param->hk);
- mpz_clear(param->nqr);
- for (i = 0; i < 5; i++) {
- mpz_clear(param->coeff[i]);
- }
- pbc_free(param->coeff);
- pbc_free(data);
-}
-
-static void g_out_str(FILE *stream, void *data) {
- g_param_ptr p = data;
- int i;
- char s[8];
- param_out_type(stream, "g");
- param_out_mpz(stream, "q", p->q);
- param_out_mpz(stream, "n", p->n);
- param_out_mpz(stream, "h", p->h);
- param_out_mpz(stream, "r", p->r);
- param_out_mpz(stream, "a", p->a);
- param_out_mpz(stream, "b", p->b);
- param_out_mpz(stream, "nk", p->nk);
- param_out_mpz(stream, "hk", p->hk);
- for (i=0; i<5; i++) {
- sprintf(s, "coeff%d", i);
- param_out_mpz(stream, s, p->coeff[i]);
- }
- param_out_mpz(stream, "nqr", p->nqr);
-}
-
-static inline void d_miller_evalfn(element_t e0,
- element_t a, element_t b, element_t c,
- element_t Qx, element_t Qy) {
- //a, b, c are in Fq
- //point Q is (Qx, Qy * sqrt(nqr)) where nqr is used to construct
- //the quadratic field extension Fqk of Fqd
- element_ptr re_out = element_x(e0);
- element_ptr im_out = element_y(e0);
-
- int i;
- int d = polymod_field_degree(re_out->field);
- for (i=0; i<d; i++) {
- element_mul(element_item(re_out, i), element_item(Qx, i), a);
- element_mul(element_item(im_out, i), element_item(Qy, i), b);
- }
- element_add(element_item(re_out, 0), element_item(re_out, 0), c);
-}
-
-static void cc_miller_no_denom_proj(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, t1;
- element_ptr t2 = a, t3 = b, t4 = c;
- element_t e0;
- element_t z, z2;
- element_ptr Zx, Zy;
- const element_ptr curve_a = curve_a_coeff(P);
- const element_ptr Px = curve_x_coord(P);
- const element_ptr Py = curve_y_coord(P);
-
- #define proj_double() { \
- /* t0 = 3x^2 + (curve_a) z^4 */ \
- element_square(t0, Zx); \
- /* element_mul_si(t0, t0, 3); */ \
- element_double(t1, t0); \
- element_add(t0, t0, t1); \
- element_square(t1, z2); \
- element_mul(t1, t1, curve_a); \
- element_add(t0, t0, t1); \
- \
- /* z_out = 2 y z */ \
- element_mul(z, Zy, z); \
- /* element_mul_si(z, z, 2); */ \
- element_double(z, z); \
- element_square(z2, z); \
- \
- /* t1 = 4 x y^2 */ \
- element_square(t2, Zy); \
- element_mul(t1, Zx, t2); \
- /* element_mul_si(t1, t1, 4); */ \
- element_double(t1, t1); \
- element_double(t1, t1); \
- \
- /* x_out = t0^2 - 2 t1 */ \
- /* element_mul_si(t3, t1, 2); */ \
- element_double(t3, t1); \
- element_square(Zx, t0); \
- element_sub(Zx, Zx, t3); \
- \
- /* t2 = 8y^4 */ \
- element_square(t2, t2); \
- /* element_mul_si(t2, t2, 8); */ \
- element_double(t2, t2); \
- element_double(t2, t2); \
- element_double(t2, t2); \
- \
- /* y_out = t0(t1 - x_out) - t2 */ \
- element_sub(t1, t1, Zx); \
- element_mul(t0, t0, t1); \
- element_sub(Zy, t0, t2); \
- }
-
- #define proj_mixin() { \
- /* t2 = Px z^2 */ \
- element_mul(t2, z2, Px); \
- \
- /* t3 = Zx - t2 */ \
- element_sub(t3, Zx, t2); \
- \
- /* t0 = Py z^3 */ \
- element_mul(t0, z2, Py); \
- element_mul(t0, t0, z); \
- \
- /* t1 = Zy - t0 */ \
- element_sub(t1, Zy, t0); \
- \
- /* e7 = Zx + t2, use t2 to double for e7 */ \
- element_add(t2, Zx, t2); \
- \
- /* e8 = Zy + t0, use t0 to double for e8 */ \
- element_add(t0, Zy, t0); \
- \
- /* z = z t3 */ \
- element_mul(z, z, t3); \
- element_square(z2, z); \
- \
- /* Zx = t1^2 - e7 t3^2 */ \
- /* t3 now holds t3^3, */ \
- /* t4 holds e7 t3^2 */ \
- element_square(t4, t3); \
- element_mul(t3, t4, t3); \
- element_square(Zx, t1); \
- element_mul(t4, t2, t4); \
- element_sub(Zx, Zx, t4); \
- \
- /* t4 = e7 t3^2 - 2 Zx */ \
- element_sub(t4, t4, Zx); \
- element_sub(t4, t4, Zx); \
- \
- /* Zy = (t4 t1 - e8 t3^3)/2 */ \
- element_mul(t4, t4, t1); \
- element_mul(t0, t0, t3); \
- element_sub(t4, t4, t0); \
- element_halve(Zy, t4); \
- }
-
- #define do_tangent() { \
- /* a = -(3x^2 + cca z^4) */ \
- /* b = 2 y z^3 */ \
- /* c = -(2 y^2 + x a) */ \
- /* a = z^2 a */ \
- element_square(a, z2); \
- element_mul(a, a, curve_a); \
- element_square(b, Zx); \
- /* element_mul_si(b, b, 3); */ \
- element_double(t0, b); \
- element_add(b, b, t0); \
- element_add(a, a, b); \
- element_neg(a, a); \
- \
- element_mul(b, z, z2); \
- element_mul(b, b, Zy); \
- element_mul_si(b, b, 2); \
- \
- element_mul(c, Zx, a); \
- element_mul(a, a, z2); \
- element_square(t0, Zy); \
- element_mul_si(t0, t0, 2); \
- element_add(c, c, t0); \
- element_neg(c, c); \
- \
- d_miller_evalfn(e0, a, b, c, Qx, Qy); \
- element_mul(v, v, e0); \
- }
-
- #define do_line() { \
- /* a = -(Py z^3 - Zy) */ \
- /* b = Px z^3 - Zx z */ \
- /* c = Zx z Py - Zy Px; */ \
- \
- element_mul(t0, Zx, z); \
- element_mul(t1, z2, z); \
- \
- element_mul(a, Py, t1); \
- element_sub(a, Zy, a); \
- \
- element_mul(b, Px, t1); \
- element_sub(b, b, t0); \
- \
- element_mul(t0, t0, Py); \
- element_mul(c, Zy, Px); \
- element_sub(c, t0, c); \
- \
- d_miller_evalfn(e0, a, b, c, Qx, Qy); \
- element_mul(v, v, e0); \
- }
-
- element_init(a, Px->field);
- element_init(b, a->field);
- element_init(c, a->field);
- element_init(t0, a->field);
- element_init(t1, a->field);
- element_init(e0, res->field);
- element_init(z, a->field);
- element_init(z2, a->field);
- element_set1(z);
- element_set1(z2);
-
- element_init(v, res->field);
- element_init(Z, P->field);
-
- element_set(Z, P);
- Zx = curve_x_coord(Z);
- Zy = curve_x_coord(Z);
-
- element_set1(v);
- m = mpz_sizeinbase(q, 2) - 2;
-
- for(;;) {
- do_tangent();
- if (!m) break;
- proj_double();
- if (mpz_tstbit(q, m)) {
- do_line();
- proj_mixin();
- }
- m--;
- element_square(v, v);
- }
-
- element_set(res, v);
-
- element_clear(v);
- element_clear(Z);
- element_clear(a);
- element_clear(b);
- element_clear(c);
- element_clear(t0);
- element_clear(t1);
- element_clear(e0);
- element_clear(z);
- element_clear(z2);
- #undef proj_double
- #undef proj_mixin
- #undef do_tangent
- #undef do_line
-}
-
-static void cc_miller_no_denom_affine(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;
-
- /* TODO: when exactly is this not needed?
- void do_vertical(void)
- {
- 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'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); \
- \
- 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 = mpz_sizeinbase(q, 2) - 2;
-
- 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
-}
-
-// Requires cofactor is even.
-// Requires in != out.
-// Mangles in.
-static void lucas_even(element_ptr out, element_ptr in, mpz_t cofactor) {
- 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);
- int 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);
-}
-
-static void tatepower10(element_ptr out, element_ptr in, pairing_t pairing) {
- mnt_pairing_data_ptr p = pairing->data;
- element_t e0, e1, e2, e3;
- element_init(e0, p->Fqk);
- element_init(e1, p->Fqd);
- 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;
- //see thesis
- #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); \
- polymod_const_mul(e2, inre[3], p->xpowq3); \
- element_add(e0re, e0re, e2); \
- polymod_const_mul(e2, inre[4], p->xpowq4); \
- 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); \
- polymod_const_mul(e2, inim[3], p->xpowq3); \
- element_add(e0im, e0im, e2); \
- polymod_const_mul(e2, inim[4], p->xpowq4); \
- 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); \
- polymod_const_mul(e2, inim[3], p->xpowq3); \
- element_sub(e0im, e0im, e2); \
- polymod_const_mul(e2, inim[4], p->xpowq4); \
- element_sub(e0im, e0im, e2); \
- element_sub(e0im0, e0im0, inim[0]); \
- } \
- }
- 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);
- lucas_even(out, e0, pairing->phikonr);
-
- element_clear(e0);
- element_clear(e1);
- element_clear(e2);
- element_clear(e3);
- #undef qpower
-}
-
-static void (*cc_miller_no_denom_fn)(element_t res, mpz_t q, element_t P,
- element_ptr Qx, element_ptr Qy);
-
-static void cc_pairing(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- element_ptr Qbase = in2;
- element_t Qx, Qy;
- mnt_pairing_data_ptr p = pairing->data;
-
- element_init(Qx, p->Fqd);
- element_init(Qy, p->Fqd);
- //map from twist: (x, y) --> (v^-1 x, v^-(3/2) y)
- //where v is the quadratic nonresidue used to construct the twist
- element_mul(Qx, curve_x_coord(Qbase), p->nqrinv);
- //v^-3/2 = v^-2 * v^1/2
- element_mul(Qy, curve_y_coord(Qbase), p->nqrinv2);
- cc_miller_no_denom_fn(out, pairing->r, in1, Qx, Qy);
- tatepower10(out, out, pairing);
- element_clear(Qx);
- element_clear(Qy);
-}
-
-static int cc_is_almost_coddh(element_ptr a, element_ptr b,
- element_ptr c, element_ptr d,
- pairing_t pairing) {
- int res = 0;
- element_t t0, t1, t2;
- element_t cx, cy;
- element_t dx, dy;
- mnt_pairing_data_ptr p = pairing->data;
-
- element_init(cx, p->Fqd);
- element_init(cy, p->Fqd);
- element_init(dx, p->Fqd);
- element_init(dy, p->Fqd);
-
- element_init(t0, p->Fqk);
- element_init(t1, p->Fqk);
- element_init(t2, p->Fqk);
- //map from twist: (x, y) --> (v^-1 x, v^-(3/2) y)
- //where v is the quadratic nonresidue used to construct the twist
- element_mul(cx, curve_x_coord(c), p->nqrinv);
- element_mul(dx, curve_x_coord(d), p->nqrinv);
- //v^-3/2 = v^-2 * v^1/2
- element_mul(cy, curve_y_coord(c), p->nqrinv2);
- element_mul(dy, curve_y_coord(d), p->nqrinv2);
-
- cc_miller_no_denom_fn(t0, pairing->r, a, dx, dy);
- cc_miller_no_denom_fn(t1, pairing->r, b, cx, cy);
- tatepower10(t0, t0, pairing);
- tatepower10(t1, t1, pairing);
- element_mul(t2, t0, t1);
- if (element_is1(t2)) {
- //g, g^x, h, h^-x case
- res = 1;
- } else {
- element_invert(t1, t1);
- element_mul(t2, t0, t1);
- if (element_is1(t2)) {
- //g, g^x, h, h^x case
- res = 1;
- }
- }
- element_clear(cx);
- element_clear(cy);
- element_clear(dx);
- element_clear(dy);
- element_clear(t0);
- element_clear(t1);
- element_clear(t2);
- return res;
-}
-
-struct pp_coeff_s {
- element_t a;
- element_t b;
- element_t c;
-};
-typedef struct pp_coeff_s pp_coeff_t[1];
-typedef struct pp_coeff_s *pp_coeff_ptr;
-
-static void g_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;
- int m;
- mnt_pairing_data_ptr 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++; \
- }
-
- //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);
- #define do_tangent() { \
- 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(); \
- }
-
- //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); \
- 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 = mpz_sizeinbase(q, 2) - 2;
- 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
-}
-
-static void g_pairing_pp_clear(pairing_pp_t p) {
- //TODO: better to store a sentinel value in p->data?
- mpz_ptr q = p->pairing->r;
- int m = mpz_sizeinbase(q, 2) + mpz_popcount(q) - 3;
- int i;
- pp_coeff_t *coeff = (pp_coeff_t *) p->data;
- pp_coeff_ptr pp;
- for (i=0; i<m; i++) {
- pp = coeff[i];
- element_clear(pp->a);
- element_clear(pp->b);
- element_clear(pp->c);
- }
- pbc_free(p->data);
-}
-
-static void g_pairing_pp_apply(element_ptr out, element_ptr in2, pairing_pp_t p) {
- mpz_ptr q = p->pairing->r;
- mnt_pairing_data_ptr info = p->pairing->data;
- int m = mpz_sizeinbase(q, 2) - 2;
- pp_coeff_t *coeff = (pp_coeff_t *) p->data;
- pp_coeff_ptr pp = coeff[0];
- element_ptr Qbase = in2;
- element_t e0;
- element_t Qx, Qy;
- element_t v;
- element_init_same_as(e0, out);
- element_init_same_as(v, out);
- element_init(Qx, info->Fqd);
- element_init(Qy, info->Fqd);
-
- //map from twist: (x, y) --> (v^-1 x, v^-(3/2) y)
- //where v is the quadratic nonresidue used to construct the twist
- element_mul(Qx, curve_x_coord(Qbase), info->nqrinv);
- //v^-3/2 = v^-2 * v^1/2
- element_mul(Qy, curve_y_coord(Qbase), info->nqrinv2);
-
- element_set1(out);
- for(;;) {
- d_miller_evalfn(e0, pp->a, pp->b, pp->c, Qx, Qy);
- element_mul(out, out, e0);
- pp++;
-
- if (!m) break;
-
- if (mpz_tstbit(q, m)) {
- d_miller_evalfn(e0, pp->a, pp->b, pp->c, Qx, Qy);
- element_mul(out, out, e0);
- pp++;
- }
- m--;
- element_square(out, out);
- }
- tatepower10(out, out, p->pairing);
-
- element_clear(e0);
- element_clear(Qx);
- element_clear(Qy);
- element_clear(v);
-}
-
-// in1, in2 are from E(F_q), out from F_q^2
-// Compute pairing via elliptic nets (see Stange).
-static void g_pairing_ellnet(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- mnt_pairing_data_ptr p = pairing->data;
-
- 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);
-
- //we map (x2,y2) to (-x2, i y2) before pairing
- //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, out);
- 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
-
- element_mul(element_x(d0), x2, p->nqrinv);
- element_neg(A, d0);
- element_add(element_item(element_x(A), 0), element_item(element_x(A), 0), x);
-
- element_double(C, x);
- element_add(element_item(element_x(d0), 0), element_item(element_x(d0), 0), C);
-
- element_square(dm1, A);
- element_mul(dm1, d0, dm1);
-
- element_mul(element_y(d1), y2, p->nqrinv2);
- element_set(element_item(element_x(d1), 0), y);
-
- element_square(d1, d1);
- element_sub(d1, dm1, d1);
- element_invert(B, d1);
-
- element_invert(A, A);
-
- element_mul(element_y(d1), y2, p->nqrinv2);
- element_set0(element_x(d1));
- element_neg(element_item(element_x(d1), 0), y);
- element_mul(d1, d1, A);
- element_square(d1, d1);
- element_sub(d1, d0, 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);
-
- polymod_const_mul(element_x(out), t0, element_x(u));
- polymod_const_mul(element_y(out), t0, element_y(u));
- polymod_const_mul(element_x(dm1), s0, element_x(v));
- polymod_const_mul(element_y(dm1), s0, element_y(v));
- element_sub(dm1, dm1, out);
-
- polymod_const_mul(element_x(out), t1, element_x(u));
- polymod_const_mul(element_y(out), t1, element_y(u));
- polymod_const_mul(element_x(d0), s1, element_x(v));
- polymod_const_mul(element_y(d0), s1, element_y(v));
- element_sub(d0, d0, out);
- element_mul(d0, d0, A);
-
- polymod_const_mul(element_x(out), t2, element_x(u));
- polymod_const_mul(element_y(out), t2, element_y(u));
- polymod_const_mul(element_x(d1), s2, element_x(v));
- polymod_const_mul(element_y(d1), s2, element_y(v));
- 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);
-
- polymod_const_mul(element_x(out), tm1, element_x(u));
- polymod_const_mul(element_y(out), tm1, element_y(u));
- polymod_const_mul(element_x(dm1), sm1, element_x(v));
- polymod_const_mul(element_y(dm1), sm1, element_y(v));
- element_sub(dm1, dm1, out);
-
- polymod_const_mul(element_x(out), t0, element_x(u));
- polymod_const_mul(element_y(out), t0, element_y(u));
- polymod_const_mul(element_x(d0), s0, element_x(v));
- polymod_const_mul(element_y(d0), s0, element_y(v));
- element_sub(d0, d0, out);
-
- polymod_const_mul(element_x(out), t1, element_x(u));
- polymod_const_mul(element_y(out), t1, element_y(u));
- polymod_const_mul(element_x(d1), s1, element_x(v));
- polymod_const_mul(element_y(d1), s1, element_y(v));
- element_sub(d1, d1, out);
- element_mul(d1, d1, A);
- }
- if (!m) break;
- m--;
- }
- // since c_k lies base field
- // it gets killed by the final powering
- //element_invert(c1, c1);
- //element_mul(element_x(d1), element_x(d1), c1);
- //element_mul(element_y(d1), element_y(d1), c1);
-
- tatepower10(out, d1, pairing);
-
- 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);
-}
-
-static void g_pairing_clear(pairing_t pairing) {
- field_clear(pairing->GT);
- mnt_pairing_data_ptr p = pairing->data;
-
- element_clear(p->xpowq);
- element_clear(p->xpowq2);
- element_clear(p->xpowq3);
- element_clear(p->xpowq4);
- mpz_clear(pairing->phikonr);
-
- field_clear(p->Etwist);
- field_clear(p->Eq);
- element_clear(p->nqrinv);
- element_clear(p->nqrinv2);
- field_clear(p->Fqk);
- field_clear(p->Fqd);
- field_clear(p->Fqx);
- field_clear(p->Fq);
- field_clear(pairing->Zr);
- mpz_clear(pairing->r);
- pbc_free(p);
-}
-
-static void g_pairing_option_set(pairing_t pairing, char *key, char *value) {
- UNUSED_VAR(pairing);
- if (!strcmp(key, "method")) {
- if (!strcmp(value, "miller")) {
- cc_miller_no_denom_fn = cc_miller_no_denom_proj;
- } else if (!strcmp(value, "miller-affine")) {
- cc_miller_no_denom_fn = cc_miller_no_denom_affine;
- } else if (!strcmp(value, "shipsey-stange")) {
- pairing->map = g_pairing_ellnet;
- }
- }
-}
-
-static void g_finalpow(element_ptr e) {
- element_t t0;
- element_init_same_as(t0, e->data);
- tatepower10(t0, e->data, e->field->pairing);
- element_set(e->data, t0);
- element_clear(t0);
-}
-
-// Computes a curve and sets fp to the field it is defined over using the
-// complex multiplication method, where cm holds appropriate data
-// (e.g. discriminant, field order).
-static void compute_cm_curve(g_param_ptr param, pbc_cm_ptr cm) {
- element_t hp, root;
- field_t fp, fpx;
- field_t cc;
-
- field_init_fp(fp, cm->q);
- field_init_poly(fpx, fp);
- element_init(hp, fpx);
-
- mpz_t *coefflist;
- int n = pbc_hilbert(&coefflist, cm->D);
-
- // Temporarily set the coefficient of x^{n-1} to 1 so hp has degree n - 1,
- // allowing us to use element_item().
- poly_set_coeff1(hp, n - 1);
- int i;
- for (i = 0; i < n; i++) {
- element_set_mpz(element_item(hp, i), coefflist[i]);
- }
- pbc_hilbert_free(coefflist, n);
-
- //TODO: remove x = 0, 1728 roots
- //TODO: what if there's no roots?
- //printf("hp ");
- //element_out_str(stdout, 0, hp);
- //printf("\n");
-
- element_init(root, fp);
- poly_findroot(root, hp);
- //printf("root = ");
- //element_out_str(stdout, 0, root);
- //printf("\n");
- element_clear(hp);
- field_clear(fpx);
-
- //the root is the j-invariant of our desired curve
- field_init_curve_j(cc, root, cm->n, NULL);
- element_clear(root);
-
- //we may need to twist it however
- {
- // Pick a random point P and twist the curve if it has the wrong order.
- element_t P;
- element_init(P, cc);
- element_random(P);
- element_mul_mpz(P, P, cm->n);
- if (!element_is0(P)) field_reinit_curve_twist(cc);
- element_clear(P);
- }
-
- mpz_set(param->q, cm->q);
- mpz_set(param->n, cm->n);
- mpz_set(param->h, cm->h);
- mpz_set(param->r, cm->r);
- element_to_mpz(param->a, curve_field_a_coeff(cc));
- element_to_mpz(param->b, curve_field_b_coeff(cc));
- {
- mpz_t z;
- mpz_init(z);
- //compute order of curve in F_q^k
- //n = q - t + 1 hence t = q - n + 1
- mpz_sub(z, param->q, param->n);
- mpz_add_ui(z, z, 1);
- pbc_mpz_trace_n(z, param->q, z, 10);
- mpz_pow_ui(param->nk, param->q, 10);
- mpz_sub_ui(z, z, 1);
- mpz_sub(param->nk, param->nk, z);
- mpz_mul(z, param->r, param->r);
- mpz_divexact(param->hk, param->nk, z);
- mpz_clear(z);
- }
- field_clear(cc);
- field_clear(fp);
-}
-
-static void g_init_pairing(pairing_t pairing, void *data) {
- g_param_ptr param = data;
- mnt_pairing_data_ptr p;
- element_t a, b;
- element_t irred;
- int i;
-
- mpz_init(pairing->r);
- mpz_set(pairing->r, param->r);
- field_init_fp(pairing->Zr, pairing->r);
- pairing->map = cc_pairing;
- pairing->is_almost_coddh = cc_is_almost_coddh;
-
- p = pairing->data = pbc_malloc(sizeof(mnt_pairing_data_t));
- field_init_fp(p->Fq, param->q);
- element_init(a, p->Fq);
- element_init(b, p->Fq);
- element_set_mpz(a, param->a);
- element_set_mpz(b, param->b);
- field_init_curve_ab(p->Eq, a, b, pairing->r, param->h);
-
- field_init_poly(p->Fqx, p->Fq);
- element_init(irred, p->Fqx);
-
- // First set the coefficient of x^5 to 1 so we can call element_item()
- // for the other coefficients.
- poly_set_coeff1(irred, 5);
- for (i=0; i<5; i++) {
- element_set_mpz(element_item(irred, i), param->coeff[i]);
- }
-
- field_init_polymod(p->Fqd, irred);
- element_clear(irred);
-
- p->Fqd->nqr = pbc_malloc(sizeof(element_t));
- element_init(p->Fqd->nqr, p->Fqd);
- element_set_mpz(((element_t *) p->Fqd->nqr->data)[0], param->nqr);
-
- field_init_quadratic(p->Fqk, p->Fqd);
-
- // Compute phi(k)/r = (q^4 - q^3 + ... + 1)/r.
- {
- element_ptr e = p->xpowq;
- mpz_t z0;
- mpz_ptr q = param->q;
- mpz_ptr z = pairing->phikonr;
- mpz_init(z);
- mpz_init(z0);
- mpz_set_ui(z, 1);
- mpz_sub(z, z, q);
- mpz_mul(z0, q, q);
- mpz_add(z, z, z0);
- mpz_mul(z0, z0, q);
- mpz_sub(z, z, z0);
- mpz_mul(z0, z0, q);
- mpz_add(z, z, z0);
- mpz_clear(z0);
- mpz_divexact(z, z, pairing->r);
-
- element_init(e, p->Fqd);
- element_init(p->xpowq2, p->Fqd);
- element_init(p->xpowq3, p->Fqd);
- element_init(p->xpowq4, p->Fqd);
- element_set1(((element_t *) e->data)[1]);
- element_pow_mpz(e, e, q);
-
- element_square(p->xpowq2, p->xpowq);
- element_square(p->xpowq4, p->xpowq2);
- element_mul(p->xpowq3, p->xpowq2, p->xpowq);
- }
-
- field_init_curve_ab_map(p->Etwist, p->Eq, element_field_to_polymod, p->Fqd, pairing->r, NULL);
- field_reinit_curve_twist(p->Etwist);
-
- element_init(p->nqrinv, p->Fqd);
- element_invert(p->nqrinv, field_get_nqr(p->Fqd));
- element_init(p->nqrinv2, p->Fqd);
- element_square(p->nqrinv2, p->nqrinv);
-
- mpz_t ndonr;
- mpz_init(ndonr);
- // ndonr temporarily holds the trace.
- mpz_sub(ndonr, param->q, param->n);
- mpz_add_ui(ndonr, ndonr, 1);
- // Negate because we want the order of the twist.
- mpz_neg(ndonr, ndonr);
- pbc_mpz_curve_order_extn(ndonr, param->q, ndonr, 5);
- mpz_divexact(ndonr, ndonr, param->r);
- field_curve_set_quotient_cmp(p->Etwist, ndonr);
- mpz_clear(ndonr);
-
- pairing->G1 = p->Eq;
- pairing->G2 = p->Etwist;
- pairing_GT_init(pairing, p->Fqk);
- pairing->finalpow = g_finalpow;
-
- cc_miller_no_denom_fn = cc_miller_no_denom_affine;
- pairing->option_set = g_pairing_option_set;
- pairing->pp_init = g_pairing_pp_init;
- pairing->pp_clear = g_pairing_pp_clear;
- pairing->pp_apply = g_pairing_pp_apply;
-
- pairing->clear_func = g_pairing_clear;
-
- element_clear(a);
- element_clear(b);
-}
-
-static void g_init(pbc_param_ptr p) {
- static pbc_param_interface_t interface = {{
- g_clear,
- g_init_pairing,
- g_out_str,
- }};
- p->api = interface;
- g_param_ptr param = p->data = pbc_malloc(sizeof(*param));
- mpz_init(param->q);
- mpz_init(param->n);
- mpz_init(param->h);
- mpz_init(param->r);
- mpz_init(param->a);
- mpz_init(param->b);
- mpz_init(param->nk);
- mpz_init(param->hk);
- param->coeff = NULL;
- mpz_init(param->nqr);
-}
-
-// Public interface:
-
-int pbc_param_init_g(pbc_param_ptr par, struct symtab_s *tab) {
- g_init(par);
- g_param_ptr p = par->data;
- char s[80];
-
- int err = 0;
- err += lookup_mpz(p->q, tab, "q");
- err += lookup_mpz(p->n, tab, "n");
- err += lookup_mpz(p->h, tab, "h");
- err += lookup_mpz(p->r, tab, "r");
- err += lookup_mpz(p->a, tab, "a");
- err += lookup_mpz(p->b, tab, "b");
- err += lookup_mpz(p->nk, tab, "nk");
- err += lookup_mpz(p->hk, tab, "hk");
- err += lookup_mpz(p->nqr, tab, "nqr");
-
- p->coeff = pbc_realloc(p->coeff, sizeof(mpz_t) * 5);
- int i;
- for (i = 0; i < 5; i++) {
- sprintf(s, "coeff%d", i);
- mpz_init(p->coeff[i]);
- err += lookup_mpz(p->coeff[i], tab, s);
- }
- return err;
-}
-
-void pbc_param_init_g_gen(pbc_param_t p, pbc_cm_ptr cm) {
- g_init(p);
- g_param_ptr param = p->data;
- field_t Fq, Fqx, Fqd;
- element_t irred, nqr;
- int i;
-
- compute_cm_curve(param, cm);
-
- field_init_fp(Fq, param->q);
- field_init_poly(Fqx, Fq);
- element_init(irred, Fqx);
- do {
- poly_random_monic(irred, 5);
- } while (!poly_is_irred(irred));
- field_init_polymod(Fqd, irred);
-
- // Find a quadratic nonresidue of Fqd lying in Fq.
- element_init(nqr, Fqd);
- do {
- element_random(((element_t *) nqr->data)[0]);
- } while (element_is_sqr(nqr));
-
- param->coeff = pbc_realloc(param->coeff, sizeof(mpz_t) * 5);
-
- for (i=0; i<5; i++) {
- mpz_init(param->coeff[i]);
- element_to_mpz(param->coeff[i], element_item(irred, i));
- }
- element_to_mpz(param->nqr, ((element_t *) nqr->data)[0]);
-
- element_clear(nqr);
- element_clear(irred);
-
- field_clear(Fqx);
- field_clear(Fqd);
- field_clear(Fq);
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/hilbert.c b/moon-abe/pbc-0.5.14/ecc/hilbert.c
deleted file mode 100644
index 753e70e0..00000000
--- a/moon-abe/pbc-0.5.14/ecc/hilbert.c
+++ /dev/null
@@ -1,539 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h> //for pbc_malloc, pbc_free
-#include <gmp.h>
-#include <math.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_poly.h"
-#include "pbc_hilbert.h"
-#include "pbc_memory.h"
-
-#include "misc/darray.h"
-#include "mpc.h"
-
-static mpf_t pi, eulere, recipeulere, epsilon, negepsilon;
-
-static void mpf_exp(mpf_t res, mpf_t pwr) {
- mpf_t a;
- mpf_t f0;
- int i;
-
- mpf_init(a); mpf_set(a, pwr);
-
- mpf_init(f0);
-
- mpf_set(f0, a);
- mpf_add_ui(res, a, 1);
-
- for (i=2;;i++) {
- mpf_mul(f0, f0, a);
- mpf_div_ui(f0, f0, i);
- if (mpf_sgn(f0) > 0) {
- if (mpf_cmp(f0, epsilon) < 0) break;
- } else {
- if (mpf_cmp(f0, negepsilon) > 0) break;
- }
- mpf_add(res, res, f0);
- }
-
- mpf_clear(f0);
- mpf_clear(a);
-}
-
-static void mpc_cis(mpc_t res, mpf_t theta) {
- mpf_t a;
-
- mpf_init(a); mpf_set(a, theta);
- //res = exp(i a)
- // = cos a + i sin a
- //converges quickly near the origin
- mpf_t f0;
- mpf_ptr rx = mpc_re(res), ry = mpc_im(res);
- int i;
- int toggle = 1;
-
- mpf_init(f0);
-
- mpf_set(f0, a);
- mpf_set_ui(rx, 1);
- mpf_set(ry, f0);
- i = 1;
- for(;;) {
- toggle = !toggle;
- i++;
- mpf_div_ui(f0, f0, i);
- mpf_mul(f0, f0, a);
- if (toggle) {
- mpf_add(rx, rx, f0);
- } else {
- mpf_sub(rx, rx, f0);
- }
-
- i++;
- mpf_div_ui(f0, f0, i);
- mpf_mul(f0, f0, a);
-
- if (toggle) {
- mpf_add(ry, ry, f0);
- } else {
- mpf_sub(ry, ry, f0);
- }
-
- if (mpf_sgn(f0) > 0) {
- if (mpf_cmp(f0, epsilon) < 0) break;
- } else {
- if (mpf_cmp(f0, negepsilon) > 0) break;
- }
- }
-
- mpf_clear(f0);
- mpf_clear(a);
-}
-
-// Computes q = exp(2 pi i tau).
-static void compute_q(mpc_t q, mpc_t tau) {
- mpc_t z0;
- mpf_t f0, f1;
- mpf_ptr fp0;
- unsigned long pwr;
-
- mpc_init(z0);
- mpf_init(f0);
- mpf_init(f1);
-
- //compute z0 = 2 pi i tau
- mpc_set(z0, tau);
- //first remove integral part of Re(tau)
- //since exp(2 pi i) = 1
- //it seems |Re(tau)| < 1 anyway?
- fp0 = mpc_re(z0);
- mpf_trunc(f1, fp0);
- mpf_sub(fp0, fp0, f1);
-
- mpc_mul_mpf(z0, z0, pi);
- mpc_mul_ui(z0, z0, 2);
- mpc_muli(z0, z0);
-
- //compute q = exp(z0);
- //first write z0 = A + a + b i
- //where A is a (negative) integer
- //and a, b are in [-1, 1]
- //compute e^A separately
- fp0 = mpc_re(z0);
- pwr = mpf_get_ui(fp0);
- mpf_pow_ui(f0, recipeulere, pwr);
- mpf_add_ui(fp0, fp0, pwr);
-
- mpf_exp(f1, mpc_re(z0));
- mpf_mul(f0, f1, f0);
- mpc_cis(q, mpc_im(z0));
-
- /*
- old_mpc_exp(q, z0);
- */
- mpc_mul_mpf(q, q, f0);
-
- mpc_clear(z0);
- mpf_clear(f0);
- mpf_clear(f1);
-}
-
-// Computes z = Delta(q) (see Cohen).
-static void compute_Delta(mpc_t z, mpc_t q) {
- int d;
- int n;
- int power;
- mpc_t z0, z1, z2;
-
- mpc_init(z0);
- mpc_init(z1);
- mpc_init(z2);
-
- mpc_set_ui(z0, 1);
- d = -1;
- for(n=1; n<100; n++) {
- power = n *(3 * n - 1) / 2;
- mpc_pow_ui(z1, q, power);
- mpc_pow_ui(z2, q, n);
- mpc_mul(z2, z2, z1);
- mpc_add(z1, z1, z2);
- if (d) {
- mpc_sub(z0, z0, z1);
- d = 0;
- } else {
- mpc_add(z0, z0, z1);
- d = 1;
- }
- }
-
- mpc_pow_ui(z0, z0, 24);
- mpc_mul(z, z0, q);
-
- mpc_clear(z0);
- mpc_clear(z1);
- mpc_clear(z2);
-}
-
-// Computes z = h(tau)
-// (called h() by Blake et al, f() by Cohen.)
-static void compute_h(mpc_t z, mpc_t tau) {
- mpc_t z0, z1, q;
- mpc_init(q);
- mpc_init(z0);
- mpc_init(z1);
- compute_q(q, tau);
- mpc_mul(z0, q, q);
- compute_Delta(z0, z0);
- compute_Delta(z1, q);
- mpc_div(z, z0, z1);
- mpc_clear(q);
- mpc_clear(z0);
- mpc_clear(z1);
-}
-
-// Computes j = j(tau).
-static void compute_j(mpc_t j, mpc_t tau) {
- mpc_t h;
- mpc_t z0;
- mpc_init(h);
- mpc_init(z0);
- compute_h(h, tau);
- //mpc_mul_ui(z0, h, 256);
- mpc_mul_2exp(z0, h, 8);
- mpc_add_ui(z0, z0, 1);
- mpc_pow_ui(z0, z0, 3);
- mpc_div(j, z0, h);
- mpc_clear(z0);
- mpc_clear(h);
-}
-
-static void compute_pi(int prec) {
- //Chudnovsky brothers' Ramanujan formula
- //http://www.cs.uwaterloo.ca/~alopez-o/math-faq/mathtext/node12.html
- mpz_t k1, k2, k4, k5, d;
- unsigned int k3 = 640320;
- unsigned int k6 = 53360;
- mpz_t z0, z1, z2;
- mpq_t p, q;
- mpf_t f1;
- int toggle = 1;
- int n;
- //converges fast: each term gives over 47 bits
- int nlimit = prec / 47 + 1;
-
- mpz_init(k1);
- mpz_init(k2);
- mpz_init(k4);
- mpz_init(k5);
- mpz_init(d);
- mpz_init(z0);
- mpz_init(z1);
- mpz_init(z2);
- mpq_init(q);
- mpq_init(p);
- mpf_init(f1);
-
- mpz_set_str(k1, "545140134", 10);
- mpz_set_str(k2, "13591409", 10);
- mpz_set_str(k4, "100100025", 10);
- mpz_set_str(k5, "327843840", 10);
-
- mpz_mul(d, k4, k5);
- mpz_mul_2exp(d, d, 3);
- mpq_set_ui(p, 0, 1);
-
- for (n=0; n<nlimit; n++) {
- mpz_fac_ui(z0, 6*n);
- mpz_mul_ui(z1, k1, n);
- mpz_add(z1, z1, k2);
- mpz_mul(z0, z0, z1);
-
- mpz_fac_ui(z1, 3*n);
- mpz_fac_ui(z2, n);
- mpz_pow_ui(z2, z2, 3);
- mpz_mul(z1, z1, z2);
- mpz_pow_ui(z2, d, n);
- mpz_mul(z1, z1, z2);
-
- mpz_set(mpq_numref(q), z0);
- mpz_set(mpq_denref(q), z1);
- mpq_canonicalize(q);
- if (toggle) {
- mpq_add(p, p, q);
- } else {
- mpq_sub(p, p, q);
- }
- toggle = !toggle;
- }
- mpq_inv(q, p);
- mpz_mul_ui(mpq_numref(q), mpq_numref(q), k6);
- mpq_canonicalize(q);
- mpf_set_q(pi, q);
- mpf_sqrt_ui(f1, k3);
- mpf_mul(pi, pi, f1);
- //mpf_out_str(stdout, 0, 14 * nlimit, pi);
- //printf("\n");
-
- mpz_clear(k1);
- mpz_clear(k2);
- mpz_clear(k4);
- mpz_clear(k5);
- mpz_clear(d);
- mpz_clear(z0);
- mpz_clear(z1);
- mpz_clear(z2);
- mpq_clear(q);
- mpq_clear(p);
- mpf_clear(f1);
-}
-
-static void precision_init(int prec) {
- int i;
- mpf_t f0;
-
- mpf_set_default_prec(prec);
- mpf_init2(epsilon, 2);
- mpf_init2(negepsilon, 2);
- mpf_init(recipeulere);
- mpf_init(pi);
- mpf_init(eulere);
-
- mpf_set_ui(epsilon, 1);
- mpf_div_2exp(epsilon, epsilon, prec);
- mpf_neg(negepsilon, epsilon);
-
- mpf_init(f0);
- mpf_set_ui(eulere, 1);
- mpf_set_ui(f0, 1);
- for (i=1;; i++) {
- mpf_div_ui(f0, f0, i);
- if (mpf_cmp(f0, epsilon) < 0) {
- break;
- }
- mpf_add(eulere, eulere, f0);
- }
- mpf_clear(f0);
-
- mpf_ui_div(recipeulere, 1, eulere);
-
- compute_pi(prec);
-}
-
-static void precision_clear(void) {
- mpf_clear(eulere);
- mpf_clear(recipeulere);
- mpf_clear(pi);
- mpf_clear(epsilon);
- mpf_clear(negepsilon);
-}
-
-// See Cohen; my D is -D in his notation.
-size_t pbc_hilbert(mpz_t **arr, int D) {
- int a, b;
- int t;
- int B = floor(sqrt((double) D / 3.0));
- mpc_t alpha;
- mpc_t j;
- mpf_t sqrtD;
- mpf_t f0;
- darray_t Pz;
- mpc_t z0, z1, z2;
- double d = 1.0;
- int h = 1;
- int jcount = 1;
-
- // Compute required precision.
- b = D % 2;
- for (;;) {
- t = (b*b + D) / 4;
- a = b;
- if (a <= 1) {
- a = 1;
- goto step535_4;
- }
-step535_3:
- if (!(t % a)) {
- jcount++;
- if ((a == b) || (a*a == t) || !b) {
- d += 1.0 / ((double) a);
- h++;
- } else {
- d += 2.0 / ((double) a);
- h+=2;
- }
- }
-step535_4:
- a++;
- if (a * a <= t) {
- goto step535_3;
- } else {
- b += 2;
- if (b > B) break;
- }
- }
-
- //printf("modulus: %f\n", exp(3.14159265358979 * sqrt(D)) * d * 0.5);
- d *= sqrt(D) * 3.14159265358979 / log(2);
- precision_init(d + 34);
- pbc_info("class number %d, %d bit precision", h, (int) d + 34);
-
- darray_init(Pz);
- mpc_init(alpha);
- mpc_init(j);
- mpc_init(z0);
- mpc_init(z1);
- mpc_init(z2);
- mpf_init(sqrtD);
- mpf_init(f0);
-
- mpf_sqrt_ui(sqrtD, D);
- b = D % 2;
- h = 0;
- for (;;) {
- t = (b*b + D) / 4;
- if (b > 1) {
- a = b;
- } else {
- a = 1;
- }
-step3:
- if (t % a) {
-step4:
- a++;
- if (a * a <= t) goto step3;
- } else {
- // a, b, t/a are coeffs of an appropriate primitive reduced positive
- // definite form.
- // Compute j((-b + sqrt{-D})/(2a)).
- h++;
- pbc_info("[%d/%d] a b c = %d %d %d", h, jcount, a, b, t/a);
- mpf_set_ui(f0, 1);
- mpf_div_ui(f0, f0, 2 * a);
- mpf_mul(mpc_im(alpha), sqrtD, f0);
- mpf_mul_ui(f0, f0, b);
- mpf_neg(mpc_re(alpha), f0);
-
- compute_j(j, alpha);
-if (0) {
- int i;
- for (i=Pz->count - 1; i>=0; i--) {
- printf("P %d = ", i);
- mpc_out_str(stdout, 10, 4, Pz->item[i]);
- printf("\n");
- }
-}
- if (a == b || a * a == t || !b) {
- // P *= X - j
- int i, n;
- mpc_ptr p0;
- p0 = (mpc_ptr) pbc_malloc(sizeof(mpc_t));
- mpc_init(p0);
- mpc_neg(p0, j);
- n = Pz->count;
- if (n) {
- mpc_set(z1, Pz->item[0]);
- mpc_add(Pz->item[0], z1, p0);
- for (i=1; i<n; i++) {
- mpc_mul(z0, z1, p0);
- mpc_set(z1, Pz->item[i]);
- mpc_add(Pz->item[i], z1, z0);
- }
- mpc_mul(p0, p0, z1);
- }
- darray_append(Pz, p0);
- } else {
- // P *= X^2 - 2 Re(j) X + |j|^2
- int i, n;
- mpc_ptr p0, p1;
- p0 = (mpc_ptr) pbc_malloc(sizeof(mpc_t));
- p1 = (mpc_ptr) pbc_malloc(sizeof(mpc_t));
- mpc_init(p0);
- mpc_init(p1);
- // p1 = - 2 Re(j)
- mpf_mul_ui(f0, mpc_re(j), 2);
- mpf_neg(f0, f0);
- mpf_set(mpc_re(p1), f0);
- // p0 = |j|^2
- mpf_mul(f0, mpc_re(j), mpc_re(j));
- mpf_mul(mpc_re(p0), mpc_im(j), mpc_im(j));
- mpf_add(mpc_re(p0), mpc_re(p0), f0);
- n = Pz->count;
- if (!n) {
- } else if (n == 1) {
- mpc_set(z1, Pz->item[0]);
- mpc_add(Pz->item[0], z1, p1);
- mpc_mul(p1, z1, p1);
- mpc_add(p1, p1, p0);
- mpc_mul(p0, p0, z1);
- } else {
- mpc_set(z2, Pz->item[0]);
- mpc_set(z1, Pz->item[1]);
- mpc_add(Pz->item[0], z2, p1);
- mpc_mul(z0, z2, p1);
- mpc_add(Pz->item[1], z1, z0);
- mpc_add(Pz->item[1], Pz->item[1], p0);
- for (i=2; i<n; i++) {
- mpc_mul(z0, z1, p1);
- mpc_mul(alpha, z2, p0);
- mpc_set(z2, z1);
- mpc_set(z1, Pz->item[i]);
- mpc_add(alpha, alpha, z0);
- mpc_add(Pz->item[i], z1, alpha);
- }
- mpc_mul(z0, z2, p0);
- mpc_mul(p1, p1, z1);
- mpc_add(p1, p1, z0);
- mpc_mul(p0, p0, z1);
- }
- darray_append(Pz, p1);
- darray_append(Pz, p0);
- }
- goto step4;
- }
- b+=2;
- if (b > B) break;
- }
-
- // Round polynomial and assign.
- int k = 0;
- {
- *arr = pbc_malloc(sizeof(mpz_t) * (Pz->count + 1));
- int i;
- for (i=Pz->count - 1; i>=0; i--) {
- if (mpf_sgn(mpc_re(Pz->item[i])) < 0) {
- mpf_set_d(f0, -0.5);
- } else {
- mpf_set_d(f0, 0.5);
- }
- mpf_add(f0, f0, mpc_re(Pz->item[i]));
- mpz_init((*arr)[k]);
- mpz_set_f((*arr)[k], f0);
- k++;
- mpc_clear(Pz->item[i]);
- pbc_free(Pz->item[i]);
- }
- mpz_init((*arr)[k]);
- mpz_set_ui((*arr)[k], 1);
- k++;
- }
- darray_clear(Pz);
- mpc_clear(z0);
- mpc_clear(z1);
- mpc_clear(z2);
- mpf_clear(f0);
- mpf_clear(sqrtD);
- mpc_clear(alpha);
- mpc_clear(j);
-
- precision_clear();
- return k;
-}
-
-void pbc_hilbert_free(mpz_t *arr, size_t n) {
- size_t i;
-
- for (i = 0; i < n; i++) mpz_clear(arr[i]);
- pbc_free(arr);
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/mnt.c b/moon-abe/pbc-0.5.14/ecc/mnt.c
deleted file mode 100644
index 230442fc..00000000
--- a/moon-abe/pbc-0.5.14/ecc/mnt.c
+++ /dev/null
@@ -1,496 +0,0 @@
-// Routines for finding:
-// * MNT curves with embedding degree 6
-// * Freeman curves (which have embedding degree 10)
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h> // for intptr_t
-#include <gmp.h>
-#include "pbc_mnt.h"
-#include "pbc_memory.h"
-#include "pbc_utils.h"
-#include "misc/darray.h"
-
-struct pell_solution_s {
- int count;
- mpz_t minx; //minimal solution of x^2 - Dy^2 = 1
- mpz_t miny;
- mpz_t *x;
- mpz_t *y;
-};
-typedef struct pell_solution_s pell_solution_t[1];
-typedef struct pell_solution_s *pell_solution_ptr;
-
-static void freempz(void *data) {
- mpz_clear(data);
- pbc_free(data);
-}
-
-// Solves x^2 - Dy^2 = N where D not a square.
-// For square D, we have (x+Dy)(x-Dy) = N so we look at the factors of N.
-static void general_pell(pell_solution_t ps, mpz_t D, int N) {
- // TODO: Use brute force for small D.
- int i, sgnN = N > 0 ? 1 : -1;
- intptr_t f, n;
-
- // Find square factors of N.
- darray_t listf;
- darray_init(listf);
-
- f = 1;
- for (;;) {
- n = f * f;
- if (n > abs(N)) break;
- if (!(abs(N) % n)) {
- darray_append(listf, int_to_voidp(f));
- }
- f++;
- }
-
- //a0, twice_a0 don't change once initialized
- //a1 is a_i every iteration
- //P0, P1 become P_{i-1}, P_i every iteration
- //similarly for Q0, Q1
- mpz_t a0, twice_a0, a1;
- mpz_t P0, P1;
- mpz_t Q0, Q1;
- //variables to compute the convergents
- mpz_t p0, p1, pnext;
- mpz_t q0, q1, qnext;
-
- int d;
-
- darray_t listp, listq;
- mpz_ptr zptr;
-
- mpz_init(a0);
- mpz_init(twice_a0);
- mpz_init(a1);
- mpz_init(P0); mpz_init(P1);
- mpz_init(Q0); mpz_init(Q1);
- mpz_init(p0); mpz_init(p1); mpz_init(pnext);
- mpz_init(q0); mpz_init(q1); mpz_init(qnext);
-
- darray_init(listp);
- darray_init(listq);
-
- mpz_sqrt(a0, D);
- mpz_set_ui(P0, 0);
- mpz_set_ui(Q0, 1);
-
- mpz_set(P1, a0);
- mpz_mul(Q1, a0, a0);
- mpz_sub(Q1, D, Q1);
- mpz_add(a1, a0, P1);
- mpz_tdiv_q(a1, a1, Q1);
-
- mpz_add(twice_a0, a0, a0);
-
- mpz_set(p0, a0);
- mpz_set_ui(q0, 1);
- mpz_mul(p1, a0, a1);
- mpz_add_ui(p1, p1, 1);
- mpz_set(q1, a1);
-
- d = -1;
- for(;;) {
- if (d == sgnN) {
- for (i=0; i<listf->count; i++) {
- f = (intptr_t) listf->item[i];
- if (!mpz_cmp_ui(Q1, abs(N) / (f * f))) {
-//element_printf("found %Zd, %Zd, %d\n", p0, q0, f);
- zptr = (mpz_ptr) pbc_malloc(sizeof(mpz_t));
- mpz_init(zptr);
- mpz_set(zptr, p0);
- mpz_mul_ui(zptr, p0, f);
- darray_append(listp, zptr);
- zptr = (mpz_ptr) pbc_malloc(sizeof(mpz_t));
- mpz_init(zptr);
- mpz_set(zptr, q0);
- mpz_mul_ui(zptr, q0, f);
- darray_append(listq, zptr);
- }
- }
- }
-
- if (!mpz_cmp(twice_a0, a1) && d == 1) break;
- //compute more of the continued fraction expansion
- mpz_set(P0, P1);
- mpz_mul(P1, a1, Q1);
- mpz_sub(P1, P1, P0);
- mpz_set(Q0, Q1);
- mpz_mul(Q1, P1, P1);
- mpz_sub(Q1, D, Q1);
- mpz_divexact(Q1, Q1, Q0);
- mpz_add(a1, a0, P1);
- mpz_tdiv_q(a1, a1, Q1);
-
- //compute next convergent
- mpz_mul(pnext, a1, p1);
- mpz_add(pnext, pnext, p0);
- mpz_set(p0, p1);
- mpz_set(p1, pnext);
-
- mpz_mul(qnext, a1, q1);
- mpz_add(qnext, qnext, q0);
- mpz_set(q0, q1);
- mpz_set(q1, qnext);
- d = -d;
- }
- darray_clear(listf);
-
- mpz_init(ps->minx);
- mpz_init(ps->miny);
- mpz_set(ps->minx, p0);
- mpz_set(ps->miny, q0);
- n = listp->count;
- ps->count = n;
- if (n) {
- ps->x = (mpz_t *) pbc_malloc(sizeof(mpz_t) * n);
- ps->y = (mpz_t *) pbc_malloc(sizeof(mpz_t) * n);
- for (i = 0; i < n; i++) {
- mpz_init(ps->x[i]);
- mpz_init(ps->y[i]);
- mpz_set(ps->x[i], (mpz_ptr) listp->item[i]);
- mpz_set(ps->y[i], (mpz_ptr) listq->item[i]);
- }
- }
-
- mpz_clear(a0);
- mpz_clear(twice_a0);
- mpz_clear(a1);
- mpz_clear(P0); mpz_clear(P1);
- mpz_clear(Q0); mpz_clear(Q1);
- mpz_clear(p0); mpz_clear(p1); mpz_clear(pnext);
- mpz_clear(q0); mpz_clear(q1); mpz_clear(qnext);
-
- darray_forall(listp, freempz);
- darray_forall(listq, freempz);
- darray_clear(listp);
- darray_clear(listq);
-}
-
-static void pell_solution_clear(pell_solution_t ps) {
- int i, n = ps->count;
-
- if (n) {
- for (i=0; i<n; i++) {
- mpz_clear(ps->x[i]);
- mpz_clear(ps->y[i]);
- }
- pbc_free(ps->x);
- pbc_free(ps->y);
- }
- mpz_clear(ps->minx);
- mpz_clear(ps->miny);
-}
-
-void pbc_cm_init(pbc_cm_t cm) {
- mpz_init(cm->q);
- mpz_init(cm->r);
- mpz_init(cm->h);
- mpz_init(cm->n);
-}
-
-void pbc_cm_clear(pbc_cm_t cm) {
- mpz_clear(cm->q);
- mpz_clear(cm->r);
- mpz_clear(cm->h);
- mpz_clear(cm->n);
-}
-
-static int mnt_step2(int (*callback)(pbc_cm_t, void *), void *data,
- unsigned int D, mpz_t U) {
- int d;
- mpz_t n, l, q;
- mpz_t p;
- mpz_t r, cofac;
-
- mpz_init(l);
- mpz_mod_ui(l, U, 6);
- if (!mpz_cmp_ui(l, 1)) {
- mpz_sub_ui(l, U, 1);
- d = 1;
- } else if (!mpz_cmp_ui(l, 5)) {
- mpz_add_ui(l, U, 1);
- d = -1;
- } else {
- mpz_clear(l);
- return 0;
- }
-
- mpz_divexact_ui(l, l, 3);
- mpz_init(q);
-
- mpz_mul(q, l, l);
- mpz_add_ui(q, q, 1);
- if (!mpz_probab_prime_p(q, 10)) {
- mpz_clear(q);
- mpz_clear(l);
- return 0;
- }
-
- mpz_init(n);
- if (d < 0) {
- mpz_sub(n, q, l);
- } else {
- mpz_add(n, q, l);
- }
-
- mpz_init(p);
- mpz_init(r);
- mpz_init(cofac);
- {
- mpz_set_ui(cofac, 1);
- mpz_set(r, n);
- mpz_set_ui(p, 2);
- if (!mpz_probab_prime_p(r, 10)) for(;;) {
- if (mpz_divisible_p(r, p)) do {
- mpz_mul(cofac, cofac, p);
- mpz_divexact(r, r, p);
- } while (mpz_divisible_p(r, p));
- if (mpz_probab_prime_p(r, 10)) break;
- //TODO: use a table of primes instead?
- mpz_nextprime(p, p);
- if (mpz_sizeinbase(p, 2) > 16) {
- //printf("has 16+ bit factor\n");
- mpz_clear(r);
- mpz_clear(p);
- mpz_clear(cofac);
- mpz_clear(q);
- mpz_clear(l);
- mpz_clear(n);
- return 0;
- }
- }
- }
-
- pbc_cm_t cm;
- pbc_cm_init(cm);
- cm->k = 6;
- cm->D = D;
- mpz_set(cm->q, q);
- mpz_set(cm->r, r);
- mpz_set(cm->h, cofac);
- mpz_set(cm->n, n);
- int res = callback(cm, data);
- pbc_cm_clear(cm);
-
- mpz_clear(cofac);
- mpz_clear(r);
- mpz_clear(p);
- mpz_clear(q);
- mpz_clear(l);
- mpz_clear(n);
- return res;
-}
-
-int pbc_cm_search_d(int (*callback)(pbc_cm_t, void *), void *data,
- unsigned int D, unsigned int bitlimit) {
- mpz_t D3;
- mpz_t t0, t1, t2;
-
- mpz_init(D3);
- mpz_set_ui(D3, D * 3);
-
- if (mpz_perfect_square_p(D3)) {
- // The only squares that differ by 8 are 1 and 9,
- // which we get if U=V=1, D=3, but then l is not an integer.
- mpz_clear(D3);
- return 0;
- }
-
- mpz_init(t0);
- mpz_init(t1);
- mpz_init(t2);
-
- pell_solution_t ps;
- general_pell(ps, D3, -8);
-
- int i, n;
- int res = 0;
- n = ps->count;
- if (n) for (;;) {
- for (i=0; i<n; i++) {
- //element_printf("%Zd, %Zd\n", ps->x[i], ps->y[i]);
- res = mnt_step2(callback, data, D, ps->x[i]);
- if (res) goto toobig;
- //compute next solution as follows
- //if p, q is current solution
- //compute new solution p', q' via
- //(p + q sqrt{3D})(t + u sqrt{3D}) = p' + q' sqrt(3D)
- //where t, u is min. solution to Pell equation
- mpz_mul(t0, ps->minx, ps->x[i]);
- mpz_mul(t1, ps->miny, ps->y[i]);
- mpz_mul(t1, t1, D3);
- mpz_add(t0, t0, t1);
- if (2 * mpz_sizeinbase(t0, 2) > bitlimit + 10) goto toobig;
- mpz_mul(t2, ps->minx, ps->y[i]);
- mpz_mul(t1, ps->miny, ps->x[i]);
- mpz_add(t2, t2, t1);
- mpz_set(ps->x[i], t0);
- mpz_set(ps->y[i], t2);
- }
- }
-toobig:
-
- pell_solution_clear(ps);
- mpz_clear(t0);
- mpz_clear(t1);
- mpz_clear(t2);
- mpz_clear(D3);
- return res;
-}
-
-static int freeman_step2(int (*callback)(pbc_cm_t, void *), void *data,
- unsigned int D, mpz_t U) {
- mpz_t n, x, q;
- mpz_t p;
- mpz_t r, cofac;
- pbc_cm_t cm;
-
- mpz_init(x);
- mpz_mod_ui(x, U, 15);
- if (!mpz_cmp_ui(x, 5)) {
- mpz_sub_ui(x, U, 5);
- } else if (!mpz_cmp_ui(x, 10)) {
- mpz_add_ui(x, U, 5);
- } else {
- pbc_die("should never reach here");
- mpz_clear(x);
- return 0;
- }
-
- mpz_divexact_ui(x, x, 15);
- mpz_init(q);
- mpz_init(r);
-
- //q = 25x^4 + 25x^3 + 25x^2 + 10x + 3
- mpz_mul(r, x, x);
- mpz_add(q, x, x);
- mpz_mul_ui(r, r, 5);
- mpz_add(q, q, r);
- mpz_mul(r, r, x);
- mpz_add(q, q, r);
- mpz_mul(r, r, x);
- mpz_add(q, q, r);
- mpz_mul_ui(q, q, 5);
- mpz_add_ui(q, q, 3);
-
- if (!mpz_probab_prime_p(q, 10)) {
- mpz_clear(q);
- mpz_clear(r);
- mpz_clear(x);
- return 0;
- }
-
- //t = 10x^2 + 5x + 3
- //n = q - t + 1
- mpz_init(n);
-
- mpz_mul_ui(n, x, 5);
- mpz_mul(r, n, x);
- mpz_add(r, r, r);
- mpz_add(n, n, r);
- mpz_sub(n, q, n);
- mpz_sub_ui(n, n, 2);
-
- mpz_init(p);
- mpz_init(cofac);
- {
- mpz_set_ui(cofac, 1);
- mpz_set(r, n);
- mpz_set_ui(p, 2);
- if (!mpz_probab_prime_p(r, 10)) for(;;) {
- if (mpz_divisible_p(r, p)) do {
- mpz_mul(cofac, cofac, p);
- mpz_divexact(r, r, p);
- } while (mpz_divisible_p(r, p));
- if (mpz_probab_prime_p(r, 10)) break;
- //TODO: use a table of primes instead?
- mpz_nextprime(p, p);
- if (mpz_sizeinbase(p, 2) > 16) {
- //printf("has 16+ bit factor\n");
- mpz_clear(r);
- mpz_clear(p);
- mpz_clear(cofac);
- mpz_clear(q);
- mpz_clear(x);
- mpz_clear(n);
- return 0;
- }
- }
- }
-
- pbc_cm_init(cm);
- cm->k = 10;
- cm->D = D;
- mpz_set(cm->q, q);
- mpz_set(cm->r, r);
- mpz_set(cm->h, cofac);
- mpz_set(cm->n, n);
- int res = callback(cm, data);
- pbc_cm_clear(cm);
-
- mpz_clear(cofac);
- mpz_clear(r);
- mpz_clear(p);
- mpz_clear(q);
- mpz_clear(x);
- mpz_clear(n);
- return res;
-}
-
-int pbc_cm_search_g(int (*callback)(pbc_cm_t, void *), void *data,
- unsigned int D, unsigned int bitlimit) {
- int res = 0;
- mpz_t D15;
- mpz_t t0, t1, t2;
-
- mpz_init(D15);
- mpz_set_ui(D15, D);
- mpz_mul_ui(D15, D15, 15);
- if (mpz_perfect_square_p(D15)) {
- mpz_clear(D15);
- return 0;
- }
-
- mpz_init(t0);
- mpz_init(t1);
- mpz_init(t2);
-
- pell_solution_t ps;
- general_pell(ps, D15, -20);
-
- int i, n;
- n = ps->count;
- if (n) for (;;) {
- for (i=0; i<n; i++) {
- res = freeman_step2(callback, data, D, ps->x[i]);
- if (res) goto toobig;
- // Compute next solution as follows:
- // If p, q is current solution
- // then compute new solution p', q' via
- // (p + q sqrt{15D})(t + u sqrt{15D}) = p' + q' sqrt(15D)
- // where t, u is min. solution to Pell equation
- mpz_mul(t0, ps->minx, ps->x[i]);
- mpz_mul(t1, ps->miny, ps->y[i]);
- mpz_mul(t1, t1, D15);
- mpz_add(t0, t0, t1);
- if (2 * mpz_sizeinbase(t0, 2) > bitlimit + 10) goto toobig;
- mpz_mul(t2, ps->minx, ps->y[i]);
- mpz_mul(t1, ps->miny, ps->x[i]);
- mpz_add(t2, t2, t1);
- mpz_set(ps->x[i], t0);
- mpz_set(ps->y[i], t2);
- }
- }
-toobig:
-
- pell_solution_clear(ps);
- mpz_clear(t0);
- mpz_clear(t1);
- mpz_clear(t2);
- mpz_clear(D15);
- return res;
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/mpc.c b/moon-abe/pbc-0.5.14/ecc/mpc.c
deleted file mode 100644
index e5341f99..00000000
--- a/moon-abe/pbc-0.5.14/ecc/mpc.c
+++ /dev/null
@@ -1,122 +0,0 @@
-//GMP based complex floats
-#include <stdio.h>
-#include <gmp.h>
-#include "mpc.h"
-
-//(a+bi)(c+di) = ac - bd + ((a+b)(c+d) - ac - bd)i
-void mpc_mul(mpc_t res, mpc_t z0, mpc_t z1)
-{
- mpf_t ac, bd, f0;
- mpf_init(ac);
- mpf_init(bd);
- mpf_init(f0);
- mpf_mul(ac, z0->a, z1->a);
- mpf_mul(bd, z0->b, z1->b);
- mpf_add(f0, z0->a, z0->b);
- mpf_add(res->b, z1->a, z1->b);
- mpf_mul(res->b, res->b, f0);
- mpf_sub(res->b, res->b, ac);
- mpf_sub(res->b, res->b, bd);
- mpf_sub(res->a, ac, bd);
- mpf_clear(f0);
- mpf_clear(ac);
- mpf_clear(bd);
-}
-
-void mpc_mul_2exp(mpc_t res, mpc_t z, unsigned long int e)
-{
- mpf_mul_2exp(res->a, z->a, e);
- mpf_mul_2exp(res->b, z->b, e);
-}
-
-//(a+bi)^2 = (a-b)(a+b) + 2abi
-void mpc_sqr(mpc_t res, mpc_t z)
-{
- mpf_t f0, f1;
- mpf_init(f0);
- mpf_init(f1);
- mpf_add(f0, z->a, z->b);
- mpf_sub(f1, z->a, z->b);
- mpf_mul(f0, f0, f1);
- mpf_mul(f1, z->a, z->b);
- mpf_set(res->a, f0);
- mpf_add(res->b, f1, f1);
- mpf_clear(f0);
- mpf_clear(f1);
-}
-
-//1/(a+bi) = (1/(a^2 + b^2))(a-bi)
-//naive. TODO: use one that is less prone to (over/under)flows/precision loss
-void mpc_inv(mpc_t res, mpc_t z)
-{
- mpf_t f0, f1;
- mpf_init(f0);
- mpf_init(f1);
- mpf_mul(f0, z->a, z->a);
- mpf_mul(f1, z->b, z->b);
- mpf_add(f0, f0, f1);
- mpf_ui_div(f0, 1, f0);
- mpf_mul(res->a, z->a, f0);
- mpf_neg(f0, f0);
- mpf_mul(res->b, z->b, f0);
- mpf_clear(f0);
- mpf_clear(f1);
-}
-
-void mpc_div(mpc_t res, mpc_t z0, mpc_t z1)
-{
- mpc_t c0;
- mpc_init(c0);
- mpc_inv(c0, z1);
- mpc_mul(res, z0, c0);
- mpc_clear(c0);
-}
-
-size_t mpc_out_str(FILE *stream, int base, size_t n_digits, mpc_t op)
-{
- size_t result, status;
- result = mpf_out_str(stream, base, n_digits, op->a);
- if (!result) return 0;
- if (mpf_sgn(op->b) >= 0) {
- if (EOF == fputc('+', stream)) return 0;
- result++;
- }
- status = mpf_out_str(stream, base, n_digits, op->b);
- if (!status) return 0;
- if (EOF == fputc('i', stream)) return 0;
- return result + status + 1;
-}
-
-void mpc_pow_ui(mpc_t res, mpc_t z, unsigned int n)
-{
- unsigned int m;
- mpc_t z0;
- mpc_init(z0);
-
- //set m to biggest power of 2 less than n
- for (m = 1; m <= n; m <<= 1);
- m >>= 1;
-
- mpf_set_ui(z0->a, 1);
- mpf_set_ui(z0->b, 0);
- while (m) {
- mpc_mul(z0, z0, z0);
- if (m & n) {
- mpc_mul(z0, z0, z);
- }
- m >>= 1;
- }
- mpc_set(res, z0);
- mpc_clear(z0);
-}
-
-void mpc_muli(mpc_t res, mpc_t z)
-{
- //i(a+bi) = -b + ai
- mpf_t f0;
- mpf_init(f0);
- mpf_neg(f0, z->b);
- mpf_set(res->b, z->a);
- mpf_set(res->a, f0);
- mpf_clear(f0);
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/mpc.h b/moon-abe/pbc-0.5.14/ecc/mpc.h
deleted file mode 100644
index 3588586b..00000000
--- a/moon-abe/pbc-0.5.14/ecc/mpc.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Complex floats.
-// Called mpc_t, these complex numbers are built on GMP's mpf_t type.
-
-// Requires:
-// * stdio.h
-// * gmp.h
-
-#ifndef __PBC_MPC_H__
-#define __PBC_MPC_H__
-
-#pragma GCC visibility push(hidden)
-
-struct mpc_s {
- mpf_t a;
- mpf_t b;
-};
-typedef struct mpc_s mpc_t[1];
-typedef struct mpc_s *mpc_ptr;
-
-static inline void mpc_init(mpc_ptr c) {
- mpf_init(c->a);
- mpf_init(c->b);
-}
-
-static inline void mpc_clear(mpc_ptr c) {
- mpf_clear(c->a);
- mpf_clear(c->b);
-}
-
-static inline mpf_ptr mpc_re(mpc_ptr c) {
- return c->a;
-}
-
-static inline mpf_ptr mpc_im(mpc_ptr c) {
- return c->b;
-}
-
-static inline void mpc_add(mpc_ptr res, mpc_ptr z0, mpc_ptr z1) {
- mpf_add(res->a, z0->a, z1->a);
- mpf_add(res->b, z0->b, z1->b);
-}
-
-static inline void mpc_sub(mpc_ptr res, mpc_ptr z0, mpc_ptr z1) {
- mpf_sub(res->a, z0->a, z1->a);
- mpf_sub(res->b, z0->b, z1->b);
-}
-
-static inline void mpc_neg(mpc_ptr res, mpc_ptr z) {
- mpf_neg(res->a, z->a);
- mpf_neg(res->b, z->b);
-}
-
-static inline void mpc_conj(mpc_ptr res, mpc_ptr z) {
- mpf_set(res->a, z->a);
- mpf_neg(res->b, z->b);
-}
-
-static inline void mpc_set(mpc_t res, mpc_t z) {
- mpf_set(res->a, z->a);
- mpf_set(res->b, z->b);
-}
-
-static inline void mpc_set_ui(mpc_t res, unsigned long int n) {
- mpf_set_ui(res->a, n);
- mpf_set_ui(res->b, 0);
-}
-
-static inline void mpc_add_ui(mpc_t res, mpc_t z, unsigned long int n) {
- mpf_add_ui(res->a, z->a, n);
-}
-
-static inline void mpc_mul_ui(mpc_t res, mpc_t z, unsigned long int n) {
- mpf_mul_ui(res->a, z->a, n);
- mpf_mul_ui(res->b, z->b, n);
-}
-
-static inline void mpc_mul_mpf(mpc_t res, mpc_t z, mpf_t f) {
- mpf_mul(res->a, z->a, f);
- mpf_mul(res->b, z->b, f);
-}
-
-void mpc_mul(mpc_t res, mpc_t z0, mpc_t z1);
-void mpc_mul_2exp(mpc_t res, mpc_t z, unsigned long int);
-void mpc_div(mpc_t res, mpc_t z0, mpc_t z1);
-void mpc_muli(mpc_t res, mpc_t z);
-void mpc_sqr(mpc_t res, mpc_t z);
-void mpc_inv(mpc_t res, mpc_t z);
-size_t mpc_out_str(FILE *stream, int base, size_t n_digits, mpc_t op);
-void mpc_pow_ui(mpc_t res, mpc_t z, unsigned int n);
-
-#pragma GCC visibility pop
-
-#endif //__PBC_MPC_H__
diff --git a/moon-abe/pbc-0.5.14/ecc/pairing.c b/moon-abe/pbc-0.5.14/ecc/pairing.c
deleted file mode 100644
index 48a9c8c6..00000000
--- a/moon-abe/pbc-0.5.14/ecc/pairing.c
+++ /dev/null
@@ -1,283 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h>
-#include <string.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_poly.h"
-#include "pbc_curve.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_memory.h"
-
-static int generic_is_almost_coddh(element_ptr a, element_ptr b,
- element_ptr c, element_ptr d, pairing_t pairing) {
- int res = 0;
- element_t t0, t1;
-
- element_init(t0, pairing->GT);
- element_init(t1, pairing->GT);
- element_pairing(t0, a, d);
- element_pairing(t1, b, c);
- if (!element_cmp(t0, t1)) {
- res = 1;
- } else {
- element_mul(t0, t0, t1);
- if (element_is1(t0)) res = 1;
- }
- element_clear(t0);
- element_clear(t1);
- return res;
-}
-
-static void generic_prod_pairings(element_ptr out, element_t in1[],
- element_t in2[], int n, pairing_t pairing) {
- pairing->map(out, in1[0], in2[0], pairing);
- element_t tmp;
- element_init_same_as(tmp, out);
- int i;
- for(i = 1; i < n; i++) {
- pairing->map(tmp, in1[i], in2[i], pairing);
- element_mul(out, out, tmp);
- }
- element_clear(tmp);
-}
-
-static void phi_warning(element_ptr out, element_ptr in, pairing_ptr pairing) {
- UNUSED_VAR(out);
- UNUSED_VAR(in);
- UNUSED_VAR(pairing);
- printf("Phi() not implemented for this pairing type yet!\n");
-}
-
-static void default_option_set(struct pairing_s *pairing, char *key, char *value) {
- UNUSED_VAR(pairing);
- UNUSED_VAR(key);
- UNUSED_VAR(value);
-}
-
-static void default_pp_init(pairing_pp_t p, element_ptr in1, pairing_t pairing) {
- UNUSED_VAR(pairing);
- p->data = (void *) in1;
-}
-
-static void default_pp_apply(element_ptr out, element_ptr in2, pairing_pp_t p) {
- p->pairing->map(out, p->data, in2, p->pairing);
-}
-
-static void default_pp_clear(pairing_pp_t p) {
- UNUSED_VAR(p);
-}
-
-void pairing_init_pbc_param(pairing_t pairing, pbc_param_ptr p) {
- pairing->option_set = default_option_set;
- pairing->pp_init = default_pp_init;
- pairing->pp_clear = default_pp_clear;
- pairing->pp_apply = default_pp_apply;
- pairing->is_almost_coddh = generic_is_almost_coddh;
- pairing->phi = phi_warning;
- pairing->prod_pairings = generic_prod_pairings;
- p->api->init_pairing(pairing, p->data);
- pairing->G1->pairing = pairing;
- pairing->G2->pairing = pairing;
- pairing->GT->pairing = pairing;
-}
-
-int pairing_init_set_buf(pairing_t pairing, const char *input, size_t len) {
- pbc_param_t par;
- int res = pbc_param_init_set_buf(par, input, len);
- if (res) {
- pbc_error("error initializing pairing");
- return 1;
- }
- pairing_init_pbc_param(pairing, par);
- pbc_param_clear(par);
- return 0;
-}
-
-int pairing_init_set_str(pairing_t pairing, const char *s) {
- return pairing_init_set_buf(pairing, s, 0);
-}
-
-void pairing_clear(pairing_t pairing) {
- pairing->clear_func(pairing);
-}
-
-// TODO: it's most likely better to add extra stuff to field_t
-// so no new data structures are needed to create mulitplicative subgroups.
-// Additionally the same code could be used with curve_t
-// Will consider it later, especially if timings turn out bad
-
-static void gt_out_info(FILE *out, field_ptr f) {
- gmp_fprintf(out, "roots of unity, order %Zd, ", f->order);
- field_out_info(out, f->data);
-}
-
-static void gt_from_hash(element_ptr e, void *data, int len) {
- pairing_ptr pairing = e->field->pairing;
- element_from_hash(e->data, data, len);
- pairing->finalpow(e);
-}
-
-static void gt_random(element_ptr e) {
- pairing_ptr pairing = e->field->pairing;
- element_random(e->data);
- pairing->finalpow(e);
-}
-
-// multiplicative subgroup of a field
-static void mulg_field_clear(field_t f) {
- UNUSED_VAR(f);
-}
-
-static void mulg_init(element_ptr e) {
- e->data = pbc_malloc(sizeof(element_t));
- field_ptr f = e->field->data;
- element_init(e->data, f);
- element_set1(e->data);
-}
-
-static void mulg_clear(element_ptr e) {
- element_clear(e->data);
- pbc_free(e->data);
-}
-
-static void mulg_set(element_ptr x, element_t a) {
- element_set(x->data, a->data);
-}
-
-static int mulg_cmp(element_ptr x, element_t a) {
- return element_cmp(x->data, a->data);
-}
-
-static size_t mulg_out_str(FILE *stream, int base, element_ptr e) {
- return element_out_str(stream, base, e->data);
-}
-
-static void mulg_set_multiz(element_ptr e, multiz m) {
- return element_set_multiz(e->data, m);
-}
-
-static int mulg_set_str(element_ptr e, const char *s, int base) {
- return element_set_str(e->data, s, base);
-}
-
-static int mulg_item_count(element_ptr e) {
- return element_item_count(e->data);
-}
-
-static element_ptr mulg_item(element_ptr e, int i) {
- return element_item(e->data, i);
-}
-
-static int mulg_to_bytes(unsigned char *data, element_ptr e) {
- return element_to_bytes(data, e->data);
-}
-
-static int mulg_from_bytes(element_ptr e, unsigned char *data) {
- return element_from_bytes(e->data, data);
-}
-
-static int mulg_length_in_bytes(element_ptr e) {
- return element_length_in_bytes(e->data);
-}
-
-static int mulg_snprint(char *s, size_t n, element_ptr e) {
- return element_snprint(s, n, e->data);
-}
-
-static void mulg_to_mpz(mpz_ptr z, element_ptr e) {
- element_to_mpz(z, e->data);
-}
-
-static void mulg_set1(element_t e) {
- element_set1(e->data);
-}
-
-static void mulg_mul(element_ptr x, element_t a, element_t b) {
- element_mul(x->data, a->data, b->data);
-}
-
-static void mulg_div(element_ptr x, element_t a, element_t b) {
- element_div(x->data, a->data, b->data);
-}
-
-static void mulg_invert(element_ptr x, element_t a) {
- element_invert(x->data, a->data);
-}
-
-static int mulg_is1(element_ptr x) {
- return element_is1(x->data);
-}
-
-static void mulg_pow_mpz(element_t x, element_t a, mpz_t n) {
- element_pow_mpz(x->data, a->data, n);
-}
-
-static void mulg_pp_init(element_pp_t p, element_t in) {
- p->data = pbc_malloc(sizeof(element_pp_t));
- element_pp_init(p->data, in->data);
-}
-
-static void mulg_pp_clear(element_pp_t p) {
- element_pp_clear(p->data);
- pbc_free(p->data);
-}
-
-static void mulg_pp_pow(element_t out, mpz_ptr power, element_pp_t p) {
- element_pp_pow(out->data, power, p->data);
-}
-
-void pairing_GT_init(pairing_ptr pairing, field_t f) {
- field_ptr gt = pairing->GT;
- field_init(gt);
- gt->data = f;
- f->pairing = pairing;
- mpz_set(gt->order, pairing->r);
- gt->field_clear = mulg_field_clear;
- gt->out_info = gt_out_info;
-
- gt->init = mulg_init;
- gt->clear = mulg_clear;
- gt->set = mulg_set;
- gt->cmp = mulg_cmp;
-
- gt->out_str = mulg_out_str;
- gt->set_multiz = mulg_set_multiz;
- gt->set_str = mulg_set_str;
- gt->to_bytes = mulg_to_bytes;
- gt->from_bytes = mulg_from_bytes;
- gt->length_in_bytes = mulg_length_in_bytes;
- gt->fixed_length_in_bytes = f->fixed_length_in_bytes;
- gt->to_mpz = mulg_to_mpz;
- gt->snprint = mulg_snprint;
- gt->item = mulg_item;
- gt->item_count = mulg_item_count;
-
- // TODO: set gt->nqr to something?
- // set is_sqr, sqrt to something?
-
- // additive notation
- gt->set0 = mulg_set1;
- gt->add = mulg_mul;
- gt->sub = mulg_div;
- gt->mul_mpz = mulg_pow_mpz;
- gt->neg = mulg_invert;
- gt->is0 = mulg_is1;
-
- // multiplicative notation
- gt->set1 = mulg_set1;
- gt->mul = mulg_mul;
- gt->div = mulg_div;
- gt->pow_mpz = mulg_pow_mpz;
- gt->invert = mulg_invert;
- gt->is1 = mulg_is1;
- gt->pp_init = mulg_pp_init;
- gt->pp_clear = mulg_pp_clear;
- gt->pp_pow = mulg_pp_pow;
-
- gt->random = gt_random;
- gt->from_hash = gt_from_hash;
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/param.c b/moon-abe/pbc-0.5.14/ecc/param.c
deleted file mode 100644
index 4fa25eef..00000000
--- a/moon-abe/pbc-0.5.14/ecc/param.c
+++ /dev/null
@@ -1,220 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h> // for intptr_t
-#include <string.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_memory.h"
-#include "pbc_param.h"
-#include "pbc_a_param.h"
-#include "pbc_mnt.h"
-#include "pbc_d_param.h"
-#include "pbc_e_param.h"
-#include "pbc_f_param.h"
-#include "pbc_a1_param.h"
-#include "pbc_g_param.h"
-#include "pbc_i_param.h"
-
-#include "misc/symtab.h"
-#include "ecc/param.h"
-
-// Parser that reads a bunch of strings and places them in a symbol table.
-// TODO: Replace with Flex/Bison?
-
-enum {
- token_none = 0,
- token_langle,
- token_langleslash,
- token_rangle,
- token_word,
- token_eof,
-};
-
-struct token_s {
- int type;
- char *s;
-};
-typedef struct token_s token_t[1];
-typedef struct token_s *token_ptr;
-
-// Reads next token from `input`.
-// Returns 1 on reaching `end` (if not NULL) or '\0' is read, 0 otherwise.
-static const char *token_get(token_t tok, const char *input, const char *end) {
- char *buf;
- int n = 32;
- int i;
- char c;
- #define get() (((!end || input < end) && *input) ? (c = *input++, 0) : 1)
- // Skip whitespace and comments.
- for(;;) {
- do {
- if (get()) {
- tok->type = token_eof;
- return input;
- }
- } while (strchr(" \t\r\n", c));
- if (c == '#') {
- do {
- if (get()) {
- tok->type = token_eof;
- return input;
- }
- } while (c != '\n');
- } else break;
- }
-
- tok->type = token_word;
- pbc_free(tok->s);
- buf = (char *) pbc_malloc(n);
- i = 0;
- for (;;) {
- buf[i] = c;
- i++;
- if (i == n) {
- n += 32;
- buf = (char *) pbc_realloc(buf, n);
- }
- if (get() || strchr(" \t\r\n</>", c)) break;
- }
- buf[i] = 0;
- tok->s = buf;
- return input;
- #undef get
-}
-
-static void token_init(token_t tok) {
- tok->type = token_none;
- tok->s = NULL;
-}
-
-static void token_clear(token_t tok) {
- pbc_free(tok->s);
-}
-
-static void read_symtab(symtab_t tab, const char *input, size_t limit) {
- token_t tok;
- const char *inputend = limit ? input + limit : NULL;
- token_init(tok);
- for (;;) {
- input = token_get(tok, input, inputend);
- if (tok->type != token_word) break;
- char *key = pbc_strdup(tok->s);
- input = token_get(tok, input, inputend);
- if (tok->type != token_word) {
- pbc_free(key);
- break;
- }
- symtab_put(tab, pbc_strdup(tok->s), key);
- pbc_free(key);
- }
- token_clear(tok);
-}
-
-// These functions have hidden visibility (see header).
-
-void param_out_type(FILE *stream, char *s) {
- fprintf(stream, "type %s\n", s);
-}
-
-void param_out_mpz(FILE *stream, char *s, mpz_t z) {
- fprintf(stream, "%s ", s);
- mpz_out_str(stream, 0, z);
- fprintf(stream, "\n");
-}
-
-void param_out_int(FILE *stream, char *s, int i) {
- mpz_t z;
- mpz_init(z);
-
- mpz_set_si(z, i);
- param_out_mpz(stream, s, z);
- mpz_clear(z);
-}
-
-static const char *lookup(symtab_t tab, const char *key) {
- if (!symtab_has(tab, key)) {
- pbc_error("missing param: `%s'", key);
- return NULL;
- }
- return symtab_at(tab, key);
-}
-
-int lookup_mpz(mpz_t z, symtab_t tab, const char *key) {
- const char *data = lookup(tab, key);
- if (!data) {
- pbc_error("missing param: `%s'", key);
- return 1;
- }
- mpz_set_str(z, data, 0);
- return 0;
-}
-
-int lookup_int(int *n, symtab_t tab, const char *key) {
- mpz_t z;
- const char *data = lookup(tab, key);
- if (!data) {
- pbc_error("missing param: `%s'", key);
- return 1;
- }
- mpz_init(z);
-
- mpz_set_str(z, data, 0);
- *n = mpz_get_si(z);
- mpz_clear(z);
-
- return 0;
-}
-
-static int param_set_tab(pbc_param_t par, symtab_t tab) {
- const char *s = lookup(tab, "type");
-
- static struct {
- char *s;
- int (*fun)(pbc_param_ptr, symtab_t tab);
- } funtab[] = {
- { "a", pbc_param_init_a },
- { "d", pbc_param_init_d },
- { "e", pbc_param_init_e },
- { "f", pbc_param_init_f },
- { "g", pbc_param_init_g },
- { "a1", pbc_param_init_a1 },
- { "i", pbc_param_init_i },
- };
-
- int res = 1;
- if (s) {
- unsigned int i;
- for(i = 0; i < sizeof(funtab)/sizeof(*funtab); i++) {
- if (!strcmp(s, funtab[i].s)) {
- res = funtab[i].fun(par, tab);
- if (res) pbc_error("bad pairing parameters");
- return res;
- }
- }
- }
-
- pbc_error("unknown pairing type");
- return res;
-}
-
-// Public functions:
-
-int pbc_param_init_set_str(pbc_param_t par, const char *input) {
- symtab_t tab;
- symtab_init(tab);
- read_symtab(tab, input, 0);
- int res = param_set_tab(par, tab);
- symtab_forall_data(tab, pbc_free);
- symtab_clear(tab);
- return res;
-}
-
-int pbc_param_init_set_buf(pbc_param_t par, const char *input, size_t len) {
- symtab_t tab;
- symtab_init(tab);
- read_symtab(tab, input, len);
- int res = param_set_tab(par, tab);
- symtab_forall_data(tab, pbc_free);
- symtab_clear(tab);
- return res;
-}
diff --git a/moon-abe/pbc-0.5.14/ecc/param.h b/moon-abe/pbc-0.5.14/ecc/param.h
deleted file mode 100644
index 36cbdd36..00000000
--- a/moon-abe/pbc-0.5.14/ecc/param.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Input/output routines common to all pairing parameters.
-
-// Requires:
-// * param.h
-// * stdio.h
-// * gmp.h
-#ifndef __PARAM_UTILS_H__
-#define __PARAM_UTILS_H__
-
-#pragma GCC visibility push(hidden)
-
-void param_out_type(FILE *stream, char *s);
-void param_out_mpz(FILE *stream, char *s, mpz_t z);
-void param_out_int(FILE *stream, char *s, int i);
-// TODO: Replace with a stdarg function, e.g.
-// err = lookup("ZZi", "p", "n", "l", p->p, p->n, &p->l);
-struct symtab_s; // let "include/pbc.h" not include "misc/symtab.h"
-int lookup_int(int *n, struct symtab_s *tab, const char *key);
-int lookup_mpz(mpz_t z, struct symtab_s *tab, const char *key);
-
-#pragma GCC visibility pop
-
-#endif //__PARAM_UTILS_H__
diff --git a/moon-abe/pbc-0.5.14/ecc/singular.c b/moon-abe/pbc-0.5.14/ecc/singular.c
deleted file mode 100644
index 95f00410..00000000
--- a/moon-abe/pbc-0.5.14/ecc/singular.c
+++ /dev/null
@@ -1,447 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h> // for intptr_t
-#include <stdlib.h>
-#include <gmp.h>
-#include "pbc_utils.h"
-#include "pbc_field.h"
-#include "pbc_curve.h"
-#include "pbc_param.h"
-#include "pbc_pairing.h"
-#include "pbc_fp.h"
-#include "pbc_memory.h"
-
-//TODO: Store as integer mod ring instead and convert at last minute?
-struct point_s {
- int inf_flag;
- element_t x;
- element_t y;
-};
-typedef struct point_s *point_ptr;
-typedef struct point_s point_t[1];
-
-static void sn_init(element_ptr e) {
- field_ptr f = e->field->data;
- e->data = pbc_malloc(sizeof(point_t));
- point_ptr p = e->data;
- element_init(p->x, f);
- element_init(p->y, f);
- p->inf_flag = 1;
-}
-
-static void sn_clear(element_ptr e) {
- point_ptr p = e->data;
- element_clear(p->x);
- element_clear(p->y);
- pbc_free(e->data);
-}
-
-static void sn_set0(element_ptr x) {
- point_ptr p = x->data;
- p->inf_flag = 1;
-}
-
-static int sn_is0(element_ptr x) {
- point_ptr p = x->data;
- return p->inf_flag;
-}
-
-//singular with node: y^2 = x^3 + x^2
-static void sn_random(element_t a) {
- point_ptr p = a->data;
- element_t t;
-
- element_init(t, p->x->field);
- p->inf_flag = 0;
- do {
- element_random(p->x);
- if (element_is0(p->x)) continue;
- element_square(t, p->x);
- element_add(t, t, p->x);
- element_mul(t, t, p->x);
- } while (!element_is_sqr(t));
- element_sqrt(p->y, t);
-
- element_clear(t);
-}
-
-static inline void sn_double_no_check(point_ptr r, point_ptr p) {
- element_t lambda, e0, e1;
-
- element_init(lambda, p->x->field);
- element_init(e0, p->x->field);
- element_init(e1, p->x->field);
- //same point: double them
-
- //lambda = (3x^2 + 2x) / 2y
- element_mul_si(lambda, p->x, 3);
- element_set_si(e0, 2);
- element_add(lambda, lambda, e0);
- element_mul(lambda, lambda, p->x);
- element_add(e0, p->y, p->y);
- element_invert(e0, e0);
- element_mul(lambda, lambda, e0);
- //x1 = lambda^2 - 2x - 1
- element_add(e1, p->x, p->x);
- element_square(e0, lambda);
- element_sub(e0, e0, e1);
- element_set_si(e1, 1);
- 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;
-}
-
-static void sn_double(element_t c, element_t a) {
- point_ptr r = c->data;
- point_ptr p = a->data;
- if (p->inf_flag) {
- r->inf_flag = 1;
- return;
- }
- if (element_is0(p->y)) {
- r->inf_flag = 1;
- return;
- }
- sn_double_no_check(r, p);
-}
-
-static void sn_set(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_set(r->y, p->y);
-}
-
-static void sn_add(element_t c, element_t a, element_t b) {
- point_ptr r = c->data;
- point_ptr p = a->data;
- point_ptr q = b->data;
- if (p->inf_flag) {
- sn_set(c, b);
- return;
- }
- if (q->inf_flag) {
- sn_set(c, a);
- return;
- }
- if (!element_cmp(p->x, q->x)) {
- if (!element_cmp(p->y, q->y)) {
- if (element_is0(p->y)) {
- r->inf_flag = 1;
- return;
- } else {
- sn_double_no_check(r, p);
- return;
- }
- }
- //points are inverses of each other
- r->inf_flag = 1;
- return;
- } else {
- element_t lambda, e0, e1;
-
- element_init(lambda, p->x->field);
- element_init(e0, p->x->field);
- element_init(e1, p->x->field);
-
- //lambda = (y2-y1)/(x2-x1)
- element_sub(e0, q->x, p->x);
- element_invert(e0, e0);
- element_sub(lambda, q->y, p->y);
- element_mul(lambda, lambda, e0);
- //x3 = lambda^2 - x1 - x2 - 1
- element_square(e0, lambda);
- element_sub(e0, e0, p->x);
- element_sub(e0, e0, q->x);
- element_set1(e1);
- element_sub(e0, e0, e1);
- //y3 = (x1-x3)lambda - y1
- 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);
- }
-}
-
-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);
-}
-
-static void sn_field_clear(field_ptr c) {
- UNUSED_VAR(c);
-}
-
-/* TODO: Write a test program that uses these functions.
-
-// Nonsingular points on sn curves map to finite field elements via
-// (x, y) --> (y + x)/(y - x)
-// The reverse map is
-// a --> (4a/(a-1)^2, 4a(a+1)/(a-1)^3)
-
-void sn_point_to_field(element_t out, point_ptr P) {
- element_t e0, e1;
- if (P->inf_flag) {
- element_set1(out);
- return;
- }
- element_init(e0, out->field);
- element_init(e1, out->field);
- element_add(e0, P->y, P->x);
- element_sub(e1, P->y, P->x);
- element_invert(e1, e1);
- element_mul(out, e0, e1);
- element_clear(e0);
- element_clear(e1);
-}
-
-static void sn_field_to_point(point_ptr P, element_t in) {
- element_t e0, e1, e2;
-
- if (element_is1(in)) {
- P->inf_flag = 1;
- return;
- }
- element_init(e0, in->field);
- element_init(e1, in->field);
- element_init(e2, in->field);
-
- element_set1(e1);
- element_sub(e0, in, e1);
- element_invert(e0, e0);
-
- element_mul_si(e2, in, 4);
-
- element_add(P->y, in, e1);
-
- element_mul(e1, e0, e0);
- element_mul(P->x, e1, e2);
- element_mul(P->y, P->y, e2);
- element_mul(P->y, P->y, e0);
- element_mul(P->y, P->y, e1);
- P->inf_flag = 0;
-
- element_clear(e0);
- element_clear(e1);
- element_clear(e2);
-}
-*/
-
-static size_t sn_out_str(FILE *stream, int base, element_ptr a) {
- point_ptr p = a->data;
- size_t result, status;
- if (p->inf_flag) {
- if (EOF == fputc('O', stream)) return 0;
- return 1;
- }
- result = element_out_str(stream, base, p->x);
- if (!result) return 0;
- if (EOF == fputc(' ', stream)) return 0;
- status = element_out_str(stream, base, p->y);
- if (!status) return 0;
- return result + status + 1;
-}
-
-void naive_generic_pow_mpz(element_ptr x, element_ptr a, mpz_ptr n);
-void field_init_curve_singular_with_node(field_t c, field_t field) {
- mpz_set(c->order, field->order);
- c->data = (void *) field;
- c->init = sn_init;
- c->clear = sn_clear;
- c->random = sn_random;
- //c->from_x = cc_from_x;
- //c->from_hash = cc_from_hash;
- c->set = sn_set;
- c->invert = c->neg = sn_invert;
- c->square = c->doub = sn_double;
- c->mul = c->add = sn_add;
- c->set1 = c->set0 = sn_set0;
- c->is1 = c->is0 = sn_is0;
- c->mul_mpz = element_pow_mpz;
- c->out_str = sn_out_str;
- c->field_clear = sn_field_clear;
-}
-
-//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);
-}
-
-struct sn_pairing_data_s {
- field_t Fq, Eq;
-};
-typedef struct sn_pairing_data_s sn_pairing_data_t[1];
-typedef struct sn_pairing_data_s *sn_pairing_data_ptr;
-
-static void sn_pairing(element_ptr out, element_ptr in1, element_ptr in2,
- pairing_t pairing) {
- sn_pairing_data_ptr p = pairing->data;
- element_ptr Q = in2;
- element_t e0;
- element_t R, QR;
- element_init(R, p->Eq);
- element_init(QR, p->Eq);
- element_random(R);
- element_init(e0, out->field);
- element_add(QR, Q, R);
- sn_miller(out, pairing->r, in1, curve_x_coord(QR), curve_y_coord(QR));
- sn_miller(e0, pairing->r, in1, curve_x_coord(R), curve_y_coord(R));
- element_invert(e0, e0);
- element_mul(out, out, e0);
- //element_pow_mpz(out, out, p->tateexp);
- element_clear(R);
- element_clear(QR);
-}
-
-void pairing_init_singular_with_node(pairing_t pairing, mpz_t q) {
- sn_pairing_data_ptr p;
-
- mpz_init(pairing->r);
- mpz_sub_ui(pairing->r, q, 1);
- field_init_fp(pairing->Zr, pairing->r);
- pairing->map = sn_pairing;
-
- p = pairing->data = pbc_malloc(sizeof(sn_pairing_data_t));
- field_init_fp(p->Fq, q);
- field_init_curve_singular_with_node(p->Eq, p->Fq);
-
- //mpz_init(p->tateexp);
- //mpz_sub_ui(p->tateexp, p->Fq->order, 1);
- //mpz_divexact(p->tateexp, p->tateexp, pairing->r);
-
- pairing->G2 = pairing->G1 = p->Eq;
-
- pairing_GT_init(pairing, p->Fq);
-}