diff options
author | wukong <rebirthmonkey@gmail.com> | 2015-11-23 17:48:48 +0100 |
---|---|---|
committer | wukong <rebirthmonkey@gmail.com> | 2015-11-23 17:48:48 +0100 |
commit | fca74d4bc3569506a6659880a89aa009dc11f552 (patch) | |
tree | 4cefd06af989608ea8ebd3bc6306889e2a1ad175 /moon-abe/pbc-0.5.14/ecc | |
parent | 840ac3ebca7af381132bf7e93c1e4c0430d6b16a (diff) |
moon-abe cleanup
Change-Id: Ie1259856db03f0b9e80de3e967ec6bd1f03191b3
Diffstat (limited to 'moon-abe/pbc-0.5.14/ecc')
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/a_param.c | 2315 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/curve.c | 987 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/d_param.c | 1258 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/e_param.c | 1006 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/eta_T_3.c | 835 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/f_param.c | 599 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/g_param.c | 1435 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/hilbert.c | 539 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/mnt.c | 496 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/mpc.c | 122 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/mpc.h | 93 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/pairing.c | 283 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/param.c | 220 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/param.h | 23 | ||||
-rw-r--r-- | moon-abe/pbc-0.5.14/ecc/singular.c | 447 |
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(¶m->m, tab, "m"); - err += lookup_int(¶m->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); -} |