/* 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 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 void to_affine(void) { 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); }
static void do_tangent(element_ptr z, element_ptr V, element_ptr Q) { element_ptr Vx = curve_x_coord(V); element_ptr Vy = curve_y_coord(V); element_ptr Qx = curve_x_coord(Q); element_ptr Qy = curve_y_coord(Q); element_t a, b, c; element_init_same_as(a, Vx); element_init_same_as(b, Vx); element_init_same_as(c, Vx); //a = -slope_tangent(V.x, V.y); //b = 1; //c = -(V.y + aV.x); /* //we could multiply by -2*V.y to avoid division so: //a = -(3 Vx^2 + cc->a) //b = 2 * Vy //c = -(2 Vy^2 + a Vx); // //actually no, since fasterweil won't work if we do this */ element_square(a, Vx); //element_mul_si(a, a, 3); element_add(b, a, a); element_add(a, b, a); element_set1(b); element_add(a, a, b); element_neg(a, a); element_double(b, Vy); element_div(a, a, b); element_set1(b); element_mul(c, a, Vx); element_add(c, c, Vy); element_neg(c, c); element_printf("tan at %B: %B %B %B\n", V, a, b, c); element_mul(a, a, Qx); element_mul(b, b, Qy); element_add(c, c, a); element_add(z, c, b); element_printf("tan eval = %B\n", z); element_clear(a); element_clear(b); element_clear(c); }
static void curve_from_hash(element_t a, void *data, int len) { element_t t, t1; point_ptr p = (point_ptr)a->data; curve_data_ptr cdp = (curve_data_ptr)a->field->data; element_init(t, cdp->field); element_init(t1, cdp->field); p->inf_flag = 0; element_from_hash(p->x, data, len); for(;;) { element_square(t, p->x); element_add(t, t, cdp->a); element_mul(t, t, p->x); element_add(t, t, cdp->b); if (element_is_sqr(t)) break; // Compute x <- x^2 + 1 and try again. element_square(p->x, p->x); element_set1(t); element_add(p->x, p->x, t); } element_sqrt(p->y, t); if (element_sgn(p->y) < 0) element_neg(p->y, p->y); if (cdp->cofac) element_mul_mpz(a, a, cdp->cofac); element_clear(t); element_clear(t1); }
static val_ptr v_field_cast(val_ptr v, tree_ptr t) { // TODO: Check args, x is an element. val_ptr x = tree_eval((tree_ptr)darray_at(t->child, 0)); element_ptr e = x->elem; if (e->field == M) { if (v->field == M) return x; element_ptr e2 = element_new(v->field); if (element_is0(e)) // if 'set0' is not 'set1' in base field of GT, but we hope 'GT(0)' calls 'set1', we may directly call 'element_set0' here element_set0(e2); else if (element_is1(e)) // reason is same as above element_set1(e2); else element_set_multiz(e2, (multiz)e->data); x->elem = e2; return x; } if (v->field == M) { // Map to/from integer. TODO: Map to/from multiz instead. mpz_t z; mpz_init(z); element_to_mpz(z, e); element_clear(e); element_init(e, v->field); element_set_mpz(e, z); mpz_clear(z); } return x; }
static void do_vert(element_ptr z, element_ptr V, element_ptr Q) { element_ptr Vx = curve_x_coord(V); element_ptr Qx = curve_x_coord(Q); element_ptr Qy = curve_y_coord(Q); element_t a, b, c; element_init_same_as(a, Vx); element_init_same_as(b, Vx); element_init_same_as(c, Vx); //a = 1 //b = 0; //c = -Vx element_set1(a); element_set0(b); element_neg(c, Vx); element_printf("vert at %B: %B %B %B\n", Vx, a, b, c); element_mul(a, a, Qx); element_mul(b, b, Qy); element_add(c, c, a); element_add(z, c, b); element_printf("vert eval = %B\n", z); element_clear(a); element_clear(b); element_clear(c); }
void CipherText::langrange(element_t* ys, int index, int k, int num){ element_t delta; element_t numerator; element_t denominator; element_t temp; element_init_Zr(delta, *(this->p)); element_init_Zr(numerator, *(this->p)); element_init_Zr(denominator, *(this->p)); element_init_Zr(temp, *(this->p)); element_init_Zr(ys[index], *(this->p)); element_set0(ys[index]); int i, j; for(i = 0; i < k; i++){ //compute the langrange coefficent l element_set1(delta); for(j = 0; j < k; j++){ if( j != i){ element_set_si(numerator, index - j); element_set_si(denominator, i - j); element_div(numerator, numerator, denominator); element_mul(delta, delta, numerator); } } element_mul(temp, ys[i], delta); element_add(ys[index], ys[index], temp); } }
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 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); } }
void miller(element_t z, element_t PR, element_t R, element_t P, element_t Q) { int m = mpz_sizeinbase(order, 2) - 2; element_t Z; element_t z1; element_t x1; element_init_same_as(Z, PR); element_set(Z, P); element_set1(z); element_init_same_as(z1, z); element_init_same_as(x1, z); do_vert(x1, PR, Q); element_printf("vert(P+R) %B\n", x1); do_line(z1, P, R, Q); element_printf("line(P,R) %B\n", z1); element_div(x1, x1, z1); element_printf("x1 %B\n", x1); element_set(z, x1); for (;;) { printf("iteration %d: %d\n", m, mpz_tstbit(order,m)); element_square(z, z); element_printf("squared: %B\n", z); do_tangent(z1, Z, Q); element_mul(z, z, z1); element_double(Z, Z); do_vert(z1, Z, Q); element_div(z, z, z1); element_printf("pre-if: %B\n", z); if (mpz_tstbit(order, m)) { element_mul(z, z, x1); do_vert(z1, P, Q); element_mul(z, z, z1); element_printf("done %B\n", z); /* do_line(z1, Z, P, Q); element_mul(z, z, z1); element_add(Z, Z, P); do_vert(z1, Z, Q); element_div(z, z, z1); */ } if (!m) break; m--; } element_clear(x1); element_clear(z1); }
static void do_line(element_ptr z, element_ptr V, element_ptr P, element_ptr Q) { element_ptr Vx = curve_x_coord(V); element_ptr Vy = curve_y_coord(V); element_ptr Px = curve_x_coord(P); element_ptr Py = curve_y_coord(P); element_ptr Qx = curve_x_coord(Q); element_ptr Qy = curve_y_coord(Q); element_t a, b, c, e0; element_init_same_as(a, Vx); element_init_same_as(b, Vx); element_init_same_as(c, Vx); element_init_same_as(e0, Vx); //a = -(B.y - A.y) / (B.x - A.x); //b = 1; //c = -(A.y + a * A.x); element_sub(a, Py, Vy); element_sub(b, Vx, Px); element_div(a, a, b); element_set1(b); element_mul(c, a, Vx); element_add(c, c, Vy); element_neg(c, c); /* //but we could multiply by B.x - A.x to avoid division, so //a = -(By - Ay) //b = Bx - Ax //c = -(Ay b + a Ax); element_sub(a, Vy, Py); element_sub(b, Px, Vx); element_mul(c, Vx, Py); element_mul(e0, Vy, Px); element_sub(c, c, e0); // //actually no, since fasterweil won't work if we do this */ element_printf("line at %B: %B %B %B\n", V, a, b, c); element_mul(a, a, Qx); element_mul(b, b, Qy); element_add(c, c, a); element_add(z, c, b); element_printf(" = %B\n", z); element_clear(a); element_clear(b); element_clear(c); element_clear(e0); }
/* 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 test_gf3m_inverse(void) { element_set1(a); element_invert(b, a); EXPECT(!element_cmp(b, e1)); element_set(a, e2); element_invert(b, a); EXPECT(!element_cmp(b, e2)); element_random(a); element_invert(b, a); element_mul(a, a, b); EXPECT(!element_cmp(a, e1)); }
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; mp_bitcnt_t m = (mp_bitcnt_t)mpz_sizeinbase(q, 2); m = (m > 2 ? m - 2 : 0); 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); }
void setup(void) { field_init_gf3m(f97, 97, 12); element_init(a, f97); element_init(b, f97); element_init(e0, f97); element_init(e1, f97); element_init(e2, f97); element_set1(e1); element_neg(e2, e1); field_init_gf32m(f97_2, f97); element_init(a2, f97_2); element_init(b2, f97_2); field_init_gf33m(f97_3, f97); element_init(a3, f97_3); element_init(b3, f97_3); field_init_gf33m(f97_6, f97_2); element_init(a6, f97_6); element_init(b6, f97_6); data = pbc_malloc(f97->fixed_length_in_bytes); }
static void _witness_set_product(setup_params_t *setup, store_t *asnums, uint32_t id, element_t result) { uint32_t asnum = 0; store_iterator_t *iterator = pbgp_store_iterator_open(asnums); store_key_t key = *(STORE_KEY_SET_DATA(key, ASLIST, asnum)); element_set1(result); for (uint32_t i = 0, pos = 0, np1 = setup->n + 1; pbgp_store_iterator_uget_next(iterator, &key, NULL, NULL) == 0; i++) { if (asnum == id) { continue ; } pos = np1 - asnum + id; if (pos >= np1) { pos-- ; } assert (setup->n * 2 - 1 > pos); element_mul(result, result, setup->P[pos]); } pbgp_store_iterator_close(iterator); }
int main(int argc, char **argv) { FILE *fpairing, *ftag, *fdata, *fresult, *fplain, *fkey, *fcipher, *fpub; pairing_t pairing; paillier_pubkey_t *pub; paillier_prvkey_t *priv; element_t g, h, u, sig1, sig2, sig3, temp_pow, m, g1, g2; element_t public_key, tag, tag_prod; element_t secret_key; paillier_get_rand_t get_rand; paillier_ciphertext_t *cipher1, *cipher2; paillier_plaintext_t *plain1, *plain2; mpz_t pub_n, a, b, data2, nsquare; int count = 0, val=5; pairing_init_set_str(pairing, param_str); //mpz_init_set_str(data_sum, "0", 10); plain1 = (paillier_plaintext_t*) malloc(sizeof(paillier_plaintext_t)); plain2 = (paillier_plaintext_t*) malloc(sizeof(paillier_plaintext_t)); cipher1 = (paillier_ciphertext_t*) malloc(sizeof(paillier_ciphertext_t)); cipher2 = (paillier_ciphertext_t*) malloc(sizeof(paillier_ciphertext_t)); //pbc_demo_pairing_init(pairing, argc, argv); element_init_G1(g1, pairing); element_init_G1(g2, pairing); element_init_G2(g, pairing); element_init_G2(public_key, pairing); element_init_G1(u, pairing); element_init_G1(temp_pow, pairing); element_init_G2(public_key, pairing); element_init_G1(h, pairing); element_init_G1(m, pairing); element_init_G1(sig1, pairing); element_init_G1(sig2, pairing); element_init_G1(sig3, pairing); element_init_G1(tag, pairing); element_init_G1(tag_prod, pairing); element_init_Zr(secret_key, pairing); // mpz_init(pub_n); char *len; mpz_init(a); mpz_init(b); mpz_init(data2); printf("Short signature test\n"); len = (char *)malloc(2048*sizeof(char)); if((fpub = fopen("pub.txt", "r"))) { pub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t)); priv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t)); mpz_init(pub->n_squared); mpz_init(pub->n); fgets(len, 1000, fpub); mpz_init_set_str(pub->p, len, 10); fgets(len, 1000, fpub); mpz_init_set_str(pub->q, len, 10); fgets(len, 1000, fpub); mpz_init_set_str(pub->n_plusone, len, 10); //printf("value of nplusone : \n"); //mpz_out_str(stdout, 10, pub->n_plusone); paillier_keygen(&pub, &priv, get_rand, 0); pub->bits = mpz_sizeinbase(pub->n, 2); fclose(fpub); } //setting already known pairing parameters if((fpairing = fopen("pairing.txt", "r"))) { fgets(len, 1000, fpairing); //printf("\n %s\n", len); element_set_str(g, len, 10); //element_printf(" g = %B\n", g); fgets(len, 1000, fpairing); //printf("\n %s\n", len); element_set_str(u, len, 10); //element_printf("\n u= %B\n", u); fgets(len, 1000, fpairing); element_set_str(secret_key, len, 10); //element_printf(" secretkey %B\n",secret_key); fgets(len, 1000, fpairing); element_set_str(public_key, len, 10); //element_printf(" publickey %B\n", public_key); fgets(len, 1000, fpairing); element_set_str(h, len, 10); //element_printf(" \nh = %B\n", h); fgets(len, 1000, fpairing); mpz_init_set_str(pub_n, len, 10); //printf("\n n = "); //mpz_out_str(stdout, 10, pub_n); fclose(fpairing); } element_set1(tag_prod); ftag = fopen("./tag/output5.txt", "r"); fgets(len, 1000, ftag); element_set_str(g1, len, 10); element_printf("\ng1 = %B\n", g1); fclose(ftag); ftag = fopen("./tag/output6.txt", "r"); fgets(len, 1000, ftag); element_set_str(g2, len, 10); element_printf("\ng2 = %B\n", g2); fclose(ftag); fplain = fopen("./split/output5.txt", "r"); fgets(len, 1000, fplain); // printf("\nlen %s", len); mpz_set_str(a, len, 10); //element_printf("\na = %Zd\n", a); fclose(fplain); fplain = fopen("./split/output6.txt", "r"); fgets(len, 1000, fplain); mpz_set_str(b, len, 10); fcipher = fopen("./cipher/copy1/output5.txt", "r"); fgets(len, 1000, fcipher); mpz_init_set_str(cipher1->c, len, 10); fclose(fcipher); fcipher = fopen("./cipher/copy1/output6.txt", "r"); fgets(len, 1000, fcipher); mpz_init_set_str(cipher2->c, len, 10); fclose(fcipher); paillier_mul(pub, cipher2, cipher2, cipher1); plain1 = paillier_dec(plain1, pub, priv, cipher2); //tag mpz_t an; mpz_init(an); mpz_init(nsquare); // mpz_mul(an, a, pub_n); mpz_mul(nsquare, pub_n, pub_n); element_pow_mpz(temp_pow,u, plain1->m); element_mul(temp_pow, temp_pow, h); element_pow_zn(sig1, temp_pow, secret_key); element_printf("\n signature of plain = %B\n", sig1); //mpz_mul(an, b, pub_n); // mpz_mul(nsquare, pub_n, pub_n); element_pow_mpz(temp_pow,u, b); element_mul(temp_pow, temp_pow, h); element_pow_zn(sig2, temp_pow, secret_key); element_printf("\n signature of b = %B\n", sig2); //element_printf("\nb = %Zd\n", b); fclose(fplain); mpz_add(a, a, b); // mpz_mod(a, a, pub_n); // mpz_mul(a, a, pub_n); // mpz_mod(a, a, nsquare); count = 2; element_pow_mpz(temp_pow,u, a); mpz_set_ui(data2, count); // itoa(count, len, 10);+ //element_printf(" \nh = %B\n", h); element_pow_mpz(h, h, data2); element_mul(temp_pow, temp_pow, h); //element_printf("\n h. u^bN = %B\n", temp_pow); element_pow_zn(sig3, temp_pow, secret_key); element_printf("\n sig 3 %B\n", sig3); element_mul(g2, g2, g1); element_printf("\n Direct Product %B\n", g2); element_mul(sig2, sig1, sig2); element_printf("\n Direct Product %B\n", sig2); return 0; }
static void gf33m_set1(element_t e) { element_ptr e0 = GF33M(e)->_0, e1 = GF33M(e)->_1, e2 = GF33M(e)->_2; element_set1(e0); element_set0(e1); element_set0(e2); }
static void miller(element_t res, element_t P, element_ptr QR, element_ptr R, int n) { // Collate divisions. mp_bitcnt_t m; element_t v, vd; element_t Z; element_t a, b, c; 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_t e0, e1; mpz_t q; element_ptr Zx, Zy; 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) { \ element_sub(e0, numx, Zx); \ element_mul((e), (e), e0); \ \ element_sub(e0, denomx, Zx); \ 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); */ \ \ if (element_is0(Zy)) { \ do_vertical((e), (edenom)); \ } else { \ 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) { \ if (!element_cmp(Zx, Px)) { \ if (!element_cmp(Zy, Py)) { \ do_tangent(e, edenom); \ } else { \ do_vertical(e, edenom); \ } \ } else { \ element_sub(b, Px, Zx); \ element_sub(a, Zy, Py); \ element_mul(c, Zx, Py); \ element_mul(e0, Zy, Px); \ 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(Z, P->field); element_set(Z, P); Zx = curve_x_coord(Z); Zy = curve_y_coord(Z); element_set1(v); element_set1(vd); mpz_init(q); mpz_set_ui(q, n); m = (mp_bitcnt_t)mpz_sizeinbase(q, 2); m = (m > 2 ? m - 2 : 0); for (;;) { element_square(v, v); element_square(vd, vd); do_tangent(v, vd); element_double(Z, Z); do_vertical(vd, v); if (mpz_tstbit(q, m)) { do_line(v, vd); element_add(Z, Z, P); if (m) { do_vertical(vd, v); } } if (!m) break; m--; } mpz_clear(q); 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); #undef do_vertical #undef do_tangent #undef do_line }
static void fq_set1(element_ptr e) { eptr p = e->data; element_set1(p->x); element_set0(p->y); }
//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); }
void pbc_decrypt(struct crypto *pbc, int tl, int *nse, int ts, int use_caching, int use_product) { /* e(C_0, K_0) -> pairing(C, K[i]) * e(C_{i1}, K_{i1}) -> pairing(Ci[i], Ki[i]) * e(C_{i2}, K_{i2}) -> pairing(Ci[i], Ki[i]) */ element_t C, K[ts], Ci[tl], Ki[tl], R, A, B, M, T; int num_mul=0, num_pair=0; struct timeval st, en; int i, j; /* -------------------- setup --------------------- */ gettimeofday(&st, NULL); element_init_G1(C, pbc->pairing); element_random(C); for (i = 0; i < ts; i++) { element_init_G2(K[i], pbc->pairing); element_random(K[i]); } for (i = 0; i < tl; i++) { element_init_G1(Ci[i], pbc->pairing); element_random(Ci[i]); } for (i = 0; i < tl; i++) { element_init_G2(Ki[i], pbc->pairing); element_random(Ki[i]); } element_init_GT(R, pbc->pairing); element_init_GT(A, pbc->pairing); element_init_GT(B, pbc->pairing); element_init_GT(M, pbc->pairing); element_init_GT(T, pbc->pairing); gettimeofday(&en, NULL); printf("Setup: %lu us\n", time_diff(&st, &en)); printf("tl=%d ts=%d|", tl, ts); for (i = 0; i < ts; i++) printf("%d ", nse[i]); printf("\n"); /* ------------------ decryption ------------------ */ gettimeofday(&st, NULL); /* e(C0, K0) across all tokens */ if (use_caching) { pairing_pp_t pp; pairing_pp_init(pp, C, pbc->pairing); for (i = 0; i < ts; i++) pairing_pp_apply(R, K[i], pp); pairing_pp_clear(pp); } else for (i = 0; i < ts; i++) { pairing_apply(R, C, K[i], pbc->pairing); num_pair++; } /* prod{e(Ci1, Ki1)}prod{e(Ci2, Ki2)} across all tokens */ if (use_product) { for (i = 0; i < ts; i++) { if (!nse[i])continue; element_prod_pairing(A, Ci, Ki, nse[i]); element_prod_pairing(B, Ci, Ki, nse[i]); element_mul(M, A, B); } } else for (i = 0; i < ts; i++) { element_set1(A); for (j = 0; j < nse[i]; j++) { element_pairing(T, Ci[j], Ki[j]); element_mul(A, A, T); num_pair++; num_mul++; } element_set1(B); for (j = 0; j < nse[i]; j++) { element_pairing(T, Ci[j], Ki[j]); element_mul(B, B, T); num_pair++; num_mul++; } element_mul(M, A, B); num_mul++; } gettimeofday(&en, NULL); printf("Decryption: %lu us\n", time_diff(&st, &en)); if (use_caching || use_product) { num_pair = -1; num_mul = -1; } printf("Used %d pairings and %d multiplications\n", num_pair, num_mul); /* ------------------- cleanup -------------------- */ gettimeofday(&st, NULL); element_clear(T); element_clear(M); element_clear(B); element_clear(A); element_clear(R); element_clear(C); for (i = 0; i < ts; i++) element_clear(K[i]); for (i = 0; i < tl; i++) element_clear(Ci[i]); for (i = 0; i < tl; i++) element_clear(Ki[i]); gettimeofday(&en, NULL); printf("Cleanup: %lu us\n", time_diff(&st, &en)); }
static void mulg_set1(element_t e) { element_set1(e->data); }
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); }
void shipseystange(element_t z, element_t P, element_t Q) { mpz_t q1r; mpz_init(q1r); mpz_set_ui(q1r, 696); element_ptr x = curve_x_coord(P); element_ptr y = curve_y_coord(P); element_ptr x2 = curve_x_coord(Q); element_ptr y2 = curve_y_coord(Q); element_t v0m1, v0m2, v0m3; element_t v00, v01, v02, v03, v04; element_t v1m1, v10, v11; element_t t0, t1, t2; element_t W20inv; element_t Wm11inv; element_t W2m1inv; element_t sm2, sm1, s0, s1, s2, s3; element_t pm2, pm1, p0, p1, p2, p3; element_init_same_as(sm2, z); element_init_same_as(sm1, z); element_init_same_as(s0, z); element_init_same_as(s1, z); element_init_same_as(s2, z); element_init_same_as(s3, z); element_init_same_as(pm2, z); element_init_same_as(pm1, z); element_init_same_as(p0, z); element_init_same_as(p1, z); element_init_same_as(p2, z); element_init_same_as(p3, z); element_init_same_as(v0m3, z); element_init_same_as(v0m2, z); element_init_same_as(v0m1, z); element_init_same_as(v00, z); element_init_same_as(v01, z); element_init_same_as(v02, z); element_init_same_as(v03, z); element_init_same_as(v04, z); element_init_same_as(v1m1, z); element_init_same_as(v10, z); element_init_same_as(v11, z); element_init_same_as(W20inv, z); element_init_same_as(Wm11inv, z); element_init_same_as(W2m1inv, z); element_init_same_as(t0, z); element_init_same_as(t1, z); element_init_same_as(t2, z); element_set0(v0m1); element_set1(v00); element_neg(v0m2, v00); element_double(v01, y); element_neg(v0m3, v01); element_invert(W20inv, v01); element_sub(Wm11inv, x, x2); element_square(t1, Wm11inv); element_invert(Wm11inv, Wm11inv); element_double(t0, x); element_add(t0, t0, x2); element_mul(t1, t0, t1); element_add(t0, y, y2); element_square(t0, t0); element_sub(t0, t0, t1); element_invert(W2m1inv, t0); /* Let P=(x,y) since A=1, B=0 we have: * W(3,0) = 3x^4 + 6x^2 - 1 * W(4,0) = 4y(x^6 + 5x^4 - 5x^2 - 1) */ //t0 = x^2 element_square(t0, x); //t1 = x^4 element_square(t1, t0); //t2 = x^4 + 2 x^2 element_double(t2, t0); element_add(t2, t2, t1); //v02 = W(3,0) element_double(v02, t2); element_add(v02, v02, t2); element_add(v02, v02, v0m2); //t2 = x^4 - x^2 element_sub(t2, t1, t0); //v03 = 5(x^4 - x^2) element_double(v03, t2); element_double(v03, v03); element_add(v03, v03, t2); //t2 = x^6 element_mul(t2, t0, t1); //v03 = W(4,0) element_add(v03, v03, t2); element_add(v03, v03, v0m2); element_double(v03, v03); element_double(v03, v03); element_mul(v03, v03, y); //v04 = W(5,0) = W(2,0)^3 W(4,0) - W(3,0)^3 element_square(t0, v01); element_mul(t0, t0, v01); element_mul(v04, t0, v03); element_square(t0, v02); element_mul(t0, t0, v02); element_sub(v04, v04, t0); element_set1(v1m1); element_set1(v10); element_printf("x y: %B %B\n", x, y); element_printf("x2 y2: %B %B\n", x2, y2); element_sub(t0, x2, x); element_sub(t1, y2, y); element_div(t0, t1, t0); element_square(t0, t0); element_double(v11, x); element_add(v11, v11, x2); element_sub(v11, v11, t0); element_printf("VEC1: %B %B %B\n", v1m1, v10, v11); element_printf("VEC0: %B %B %B %B %B %B %B %B\n", v0m3, v0m2, v0m1, v00, v01, v02, v03, v04); //Double element_square(sm2, v0m2); element_square(sm1, v0m1); element_square(s0, v00); element_square(s1, v01); element_square(s2, v02); element_square(s3, v03); element_mul(pm2, v0m3, v0m1); element_mul(pm1, v0m2, v00); element_mul(p0, v0m1, v01); element_mul(p1, v00, v02); element_mul(p2, v01, v03); element_mul(p3, v02, v04); element_mul(t0, pm1, sm2); element_mul(t1, pm2, sm1); element_sub(v0m3, t0, t1); element_mul(t1, pm2, s0); element_mul(t0, p0, sm2); element_sub(v0m2, t0, t1); element_mul(v0m2, v0m2, W20inv); element_mul(t0, p0, sm1); element_mul(t1, pm1, s0); element_sub(v0m1, t0, t1); element_mul(t1, pm1, s1); element_mul(t0, p1, sm1); element_sub(v00, t0, t1); element_mul(v00, v00, W20inv); element_mul(t0, p1, s0); element_mul(t1, p0, s1); element_sub(v01, t0, t1); element_mul(t1, p0, s2); element_mul(t0, p2, s0); element_sub(v02, t0, t1); element_mul(v02, v02, W20inv); element_mul(t0, p2, s1); element_mul(t1, p1, s2); element_sub(v03, t0, t1); element_mul(t1, p1, s3); element_mul(t0, p3, s1); element_sub(v04, t0, t1); element_mul(v04, v04, W20inv); element_square(t0, v10); element_mul(t1, v1m1, v11); element_mul(t2, pm1, t0); element_mul(v1m1, t1, sm1); element_sub(v1m1, v1m1, t2); element_mul(t2, p0, t0); element_mul(v10, t1, s0); element_sub(v10, v10, t2); element_mul(t2, p1, t0); element_mul(v11, t1, s1); element_sub(v11, v11, t2); element_mul(v11, v11, Wm11inv); element_printf("VEC1: %B %B %B\n", v1m1, v10, v11); element_printf("VEC0: %B %B %B %B %B %B %B %B\n", v0m3, v0m2, v0m1, v00, v01, v02, v03, v04); //DoubleAdd element_square(sm2, v0m2); element_square(sm1, v0m1); element_square(s0, v00); element_square(s1, v01); element_square(s2, v02); element_square(s3, v03); element_mul(pm2, v0m3, v0m1); element_mul(pm1, v0m2, v00); element_mul(p0, v0m1, v01); element_mul(p1, v00, v02); element_mul(p2, v01, v03); element_mul(p3, v02, v04); element_mul(t1, pm2, s0); element_mul(t0, p0, sm2); element_sub(v0m3, t0, t1); element_mul(v0m3, v0m3, W20inv); element_mul(t0, p0, sm1); element_mul(t1, pm1, s0); element_sub(v0m2, t0, t1); element_mul(t1, pm1, s1); element_mul(t0, p1, sm1); element_sub(v0m1, t0, t1); element_mul(v0m1, v0m1, W20inv); element_mul(t0, p1, s0); element_mul(t1, p0, s1); element_sub(v00, t0, t1); element_mul(t1, p0, s2); element_mul(t0, p2, s0); element_sub(v01, t0, t1); element_mul(v01, v01, W20inv); element_mul(t0, p2, s1); element_mul(t1, p1, s2); element_sub(v02, t0, t1); element_mul(t1, p1, s3); element_mul(t0, p3, s1); element_sub(v03, t0, t1); element_mul(v03, v03, W20inv); element_mul(t0, p3, s2); element_mul(t1, p2, s3); element_sub(v04, t0, t1); element_square(t0, v10); element_mul(t1, v1m1, v11); element_mul(t2, p0, t0); element_mul(v1m1, t1, s0); element_sub(v1m1, v1m1, t2); element_mul(t2, p1, t0); element_mul(v10, t1, s1); element_sub(v10, v10, t2); element_mul(v10, v10, Wm11inv); element_mul(t2, t1, s2); element_mul(v11, p2, t0); element_sub(v11, v11, t2); element_mul(v11, v11, W2m1inv); element_printf("VEC1: %B %B %B\n", v1m1, v10, v11); element_printf("VEC0: %B %B %B %B %B %B %B %B\n", v0m3, v0m2, v0m1, v00, v01, v02, v03, v04); element_div(z, v11, v01); element_printf("prepow: %B\n", z); element_pow_mpz(z, z, q1r); mpz_clear(q1r); }
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 }
// 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 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 }
int main(void) { int i; element_t g, h; element_t w0, w1; element_t a, b; mpz_t prime, cofac; mpz_init(prime); mpz_init(order); mpz_init(cofac); mpz_set_ui(prime, 59); field_init_fp(Fq, prime); element_init(a, Fq); element_init(b, Fq); field_init_fi(Fq2, Fq); element_set1(a); element_set0(b); mpz_set_ui(order, 5); mpz_set_ui(cofac, 12); field_init_curve_ab(E, a, b, order, cofac); element_clear(a); element_clear(b); element_init(a, Fq2); element_init(b, Fq2); element_set1(a); element_set0(b); mpz_mul(cofac, cofac, cofac); field_init_curve_ab(E2, a, b, order, NULL); element_init(g, E2); element_init(h, E2); element_init(w0, Fq2); element_init(w1, Fq2); /* do { element_random(g); } while (element_is1(g)); for (i=1; i<5; i++) { element_mul(h, h, g); element_printf("%d: %B\n", i, h); element_printf("tangent = "); do_tangent(h); } */ element_set_str(g, "[[25,0],[30,0]", 0); element_set_str(h, "[[34,0],[0,30]", 0); weil(w0, g, h); element_printf("weil: %B\n", w0); element_set1(w1); for (i=1; i<6; i++) { element_mul(w1, w1, w0); element_printf("%d: %B\n", i, w1); } fasterweil(w0, g, h); element_printf("fasterweil: %B\n", w0); element_set1(w1); for (i=1; i<6; i++) { element_mul(w1, w1, w0); element_printf("%d: %B\n", i, w1); } fasterweil2(w0, g, h); element_printf("fasterweil2: %B\n", w0); tate(w0, g, h); element_printf("tate: %B\n", w0); element_set1(w1); for (i=1; i<6; i++) { element_mul(w1, w1, w0); element_printf("%d: %B\n", i, w1); } shipseystange(w0, g, h); element_printf("ss-tate: %B\n", w0); element_set1(w1); for (i=1; i<6; i++) { element_mul(w1, w1, w0); element_printf("%d: %B\n", i, w1); } return 0; }
int claim_new_epoch(char *glb[2],char *epoch[2],char *facc,char *outf,setup_params_t *setup) { int rv = 0, i = 0; epoch_item_t *ep = NULL; id_list_t *act = NULL, *rvk = NULL; rv = newepoch_init(&ep,setup); if(rv < 0) { pbgp_error("claim_new_epoch :: Cannot complete initialization process\n"); goto out1; } rv = ids_init(&ep->epls.act,&ep->epls.rvk); rv -= ids_init(&act,&rvk); if (rv < 0) { pbgp_error("claim_new_epoch :: Cannot initialize ids lists\n"); goto out2; } if (!file_exists(epoch[0]) || !file_exists(epoch[1])) { rv = -1; pbgp_error("Cannot find epoch files (%s,%s)\n",epoch[0],epoch[1]); goto out2; } rv = ids_load(epoch[0],ep->epls.act); rv -= ids_load(epoch[1],ep->epls.rvk); rv -= ids_load(glb[0],act); rv -= ids_load(glb[1],rvk); if(rv < 0) { pbgp_error("claim_new_epoch :: Cannot load ids\n"); goto out3; } if(ep->epls.act->size == 0 && ep->epls.rvk->size == 0) { rv = -1; pbgp_error("claim_new_epoch :: There are no entities to join or revoke\n"); goto out3; } //if first epoch if(!file_exists(facc)) { acc_create(ep->acc); ep->epoch = 0; } else { rv = acc_load(facc,ep->acc); if(rv < 0) { pbgp_error("claim_new_epoch :: Cannot create accumulator\n"); goto out4; } } ep->epoch = ep->acc->nep; //element_printf("ACC: %B\n",ep->acc); newepoch_gen(outf,ep,setup); //save accumulator //element_printf("ACC: %B\n",ep->acc); if(element_is0(ep->acc->elem)) { printf("ACC is 0\n"); element_set1(ep->acc->elem); } acc_save(facc,ep->epoch,ep->acc); //update global joined entities for(i = 0; i < ep->epls.act->size; i++) { ids_add(act,&ep->epls.act->head[i]); } //update global revoked entities for(i = 0; i < ep->epls.rvk->size; i++) { ids_remove(act,&ep->epls.rvk->head[i]); ids_add(rvk,&ep->epls.rvk->head[i]); } ids_save(glb[0],act); ids_save(glb[1],rvk); //delete old epoch files (or write empty list) remove(epoch[0]); remove(epoch[1]); out4: acc_clear(ep->acc); out3: ids_clear(ep->epls.act,ep->epls.rvk); ids_clear(act,rvk); out2: newepoch_clear(ep); out1: return rv; }