aboutsummaryrefslogtreecommitdiffstats
path: root/moon-abe/pbc-0.5.14/ecc/a_param.c
diff options
context:
space:
mode:
Diffstat (limited to 'moon-abe/pbc-0.5.14/ecc/a_param.c')
-rw-r--r--moon-abe/pbc-0.5.14/ecc/a_param.c2315
1 files changed, 0 insertions, 2315 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);
-}