void millertate(element_t z, element_t P, element_t Q) { element_t Z; element_t z0; element_init_same_as(Z, P); element_init_same_as(z0, z); element_set(Z, P); do_tangent(z, Z, Q); element_double(Z, Z); do_vert(z0, Z, Q); element_div(z, z, z0); element_printf("presquare: z = %B\n", z); element_square(z, z); element_printf("square: z = %B\n", z); do_tangent(z0, Z, Q); element_mul(z, z, z0); element_clear(z0); element_clear(Z); }
void tate(element_t z, element_t P, element_t Q) { mpz_t q1r; mpz_init(q1r); mpz_set_ui(q1r, 696); /* millertate(z, P, Q); element_printf("prepow: z = %B\n", z); element_pow_mpz(z, z, q1r); */ { element_t R, QR; element_t z0; element_init_same_as(R, P); element_init_same_as(QR, P); element_init_same_as(z0, z); element_random(R); element_add(QR, Q, R); millertate(z, P, QR); millertate(z0, P, R); element_div(z, z, z0); element_pow_mpz(z, z, q1r); element_clear(R); element_clear(QR); } mpz_clear(q1r); }
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 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); }
static void record(element_t asum, element_t bsum, element_t snark, darray_t hole, mpz_t counter) { snapshot_ptr ss = pbc_malloc(sizeof(struct snapshot_s)); element_init_same_as(ss->a, asum); element_init_same_as(ss->b, bsum); element_init_same_as(ss->snark, snark); element_set(ss->a, asum); element_set(ss->b, bsum); element_set(ss->snark, snark); darray_append(hole, ss); element_printf("snark %Zd: %B\n", counter, snark); }
void weil(element_t w, element_t g, element_t h) { element_t gr; element_t hs; element_t r; element_t s; element_t z, z0, z1; element_init(z, Fq2); element_init(z0, Fq2); element_init(z1, Fq2); element_init_same_as(gr, g); element_init_same_as(hs, h); element_init_same_as(r, g); element_init_same_as(s, h); element_random(r); element_random(s); //point_random always takes the same square root //why not take the other one for once? element_neg(r, r); element_set_str(r, "[[40,0],[54,0]]", 0); element_set_str(s, "[[48,55],[28,51]]", 0); element_printf("chose R = %B\n", r); element_printf("chose S = %B\n", s); element_add(gr, g, r); element_add(hs, h, s); element_printf("P+R = %B\n", gr); element_printf("Q+S = %B\n", hs); miller(z, gr, r, g, hs); miller(z0, gr, r, g, s); element_div(z1, z, z0); element_printf("num: %B\n", z1); miller(z, hs, s, h, gr); miller(z0, hs, s, h, r); element_div(w, z, z0); element_printf("denom: %B\n", w); element_div(w, z1, w); element_clear(gr); element_clear(r); element_clear(hs); element_clear(s); element_clear(z); element_clear(z0); element_clear(z1); }
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 val_ptr eval_elem(tree_ptr t) { // TODO: Write element_clone(), or at least element_new(). element_ptr e = (element_ptr)pbc_malloc(sizeof(*e)); element_init_same_as(e, t->elem); element_set(e, t->elem); return val_new_element(e); }
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); }
/* Computes Shares * * @param1: msp * @param2: input vector[s, r1, r2, ...] * @param3: output vector */ void computeShares(MSP* msp, element_t* input_array, element_t* output_array){ int i = 0; int j = 0; element_t tmp_sum, tmp_product; element_init_same_as(tmp_sum, input_array[0] ); element_init_same_as(tmp_product,tmp_sum); element_set0(tmp_sum); for(i=0; i < (msp->rows); i++){ for(j=0; j < msp->cols; j++){ element_mul_si(tmp_product, (input_array)[j],(msp->matrix)[i][j]); element_add(tmp_sum, tmp_sum, tmp_product); } element_set(output_array[i], tmp_sum); element_set0(tmp_sum); } element_clear(tmp_sum); element_clear(tmp_product); }
static val_ptr run_item(val_ptr v[]) { mpz_t z; mpz_init(z); element_to_mpz(z, v[1]->elem); int i = mpz_get_si(z); mpz_clear(z); element_ptr a = element_item(v[0]->elem, i); element_ptr e = (element_ptr)pbc_malloc(sizeof(*e)); element_init_same_as(e, a); element_set(e, a); return val_new_element(e); }
static void generic_prod_pairings(element_ptr out, element_t in1[], element_t in2[], int n, pairing_t pairing) { pairing->map(out, in1[0], in2[0], pairing); element_t tmp; element_init_same_as(tmp, out); int i; for(i = 1; i < n; i++) { pairing->map(tmp, in1[i], in2[i], pairing); element_mul(out, out, tmp); } element_clear(tmp); }
void fasterweil2(element_t w, element_t g, element_t h) { element_t gr; element_t r; element_t z, z0, z1; element_init(z, Fq2); element_init(z0, Fq2); element_init(z1, Fq2); element_init_same_as(gr, g); element_init_same_as(r, g); element_random(r); //point_random always takes the same square root //why not take the other one for once? element_set_str(r, "[[48,55],[28,51]]", 0); element_printf("chose R = %B\n", r); element_add(gr, g, r); element_printf("P+R = %B\n", gr); miller(w, gr, r, g, h); element_printf("num: %B\n", w); millertate(z, h, gr); millertate(z0, h, r); element_div(z1, z, z0); element_printf("denom: %B\n", z1); element_div(w, w, z1); element_clear(z); element_clear(z0); element_clear(z1); element_clear(gr); element_clear(r); }
void fasterweil(element_t w, element_t g, element_t h) { element_t hs; element_t s; element_t z, z0, z1; element_init(z, Fq2); element_init(z0, Fq2); element_init(z1, Fq2); element_init_same_as(hs, h); element_init_same_as(s, h); element_random(s); //point_random always takes the same square root //why not take the other one for once? element_set_str(s, "[[48,55],[28,51]]", 0); element_printf("chose S = %B\n", s); element_add(hs, h, s); element_printf("Q+S = %B\n", hs); millertate(z, g, hs); millertate(z0, g, s); element_div(z1, z, z0); element_printf("num: %B\n", z1); miller(w, hs, s, h, g); element_printf("denom: %B\n", w); element_div(w, z1, w); element_clear(z); element_clear(z0); element_clear(z1); element_clear(hs); element_clear(s); }
// g, h in some group of order r // finds x such that g^x = h // will hang if no such x exists // x in some field_t that set_mpz makes sense for void element_dlog_brute_force(element_t x, element_t g, element_t h) { element_t g0; mpz_t count; mpz_init(count); element_init_same_as(g0, g); element_set(g0, g); mpz_set_ui(count, 1); while (element_cmp(g0, h)) { element_mul(g0, g0, g); //element_printf("g0^%Zd = %B\n", count, g0); mpz_add_ui(count, count, 1); } element_set_mpz(x, count); mpz_clear(count); element_clear(g0); }
static int curve_cmp(element_ptr a, element_ptr b) { if (a == b) { return 0; } else { // If we're working with a quotient group we must account for different // representatives of the same coset. curve_data_ptr cdp = (curve_data_ptr)a->field->data; if (cdp->quotient_cmp) { element_t e; element_init_same_as(e, a); element_div(e, a, b); element_pow_mpz(e, e, cdp->quotient_cmp); int result = !element_is1(e); element_clear(e); return result; } return point_cmp((point_ptr)a->data, (point_ptr)b->data); } }
// Requires cofactor is even. TODO: This seems to contradict a comment below. // Requires in != out. // Mangles in. static void lucas_even(element_ptr out, element_ptr in, mpz_t cofactor) { if (element_is1(in)) { element_set(out, in); return; } element_t temp; element_init_same_as(temp, out); element_ptr in0 = element_x(in); element_ptr in1 = element_y(in); element_ptr v0 = element_x(out); element_ptr v1 = element_y(out); element_ptr t0 = element_x(temp); element_ptr t1 = element_y(temp); size_t j; element_set_si(t0, 2); element_double(t1, in0); element_set(v0, t0); element_set(v1, t1); j = mpz_sizeinbase(cofactor, 2) - 1; for (;;) { if (!j) { element_mul(v1, v0, v1); element_sub(v1, v1, t1); element_square(v0, v0); element_sub(v0, v0, t0); break; } if (mpz_tstbit(cofactor, j)) { element_mul(v0, v0, v1); element_sub(v0, v0, t1); element_square(v1, v1); element_sub(v1, v1, t0); } else { element_mul(v1, v0, v1); element_sub(v1, v1, t1); element_square(v0, v0); element_sub(v0, v0, t0); } j--; } // Assume cofactor = (q^2 - q + 1) / r is odd // thus v1 = V_k, v0 = V_{k-1} // U = (P v1 - 2 v0) / (P^2 - 4) element_double(v0, v0); element_mul(in0, t1, v1); element_sub(in0, in0, v0); element_square(t1, t1); element_sub(t1, t1, t0); element_sub(t1, t1, t0); element_halve(v0, v1); element_div(v1, in0, t1); element_mul(v1, v1, in1); element_clear(temp); }
// 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); }
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 val_ptr v_elem_eval(val_ptr v) { element_ptr e = (element_ptr)pbc_malloc(sizeof(*e)); element_init_same_as(e, v->elem); element_set(e, v->elem); return val_new_element(e); }