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 fi_sqrt(element_ptr n, element_ptr e) { eptr p = e->data; eptr r = n->data; element_t e0, e1, e2; // If (a+bi)^2 = x+yi then 2a^2 = x +- sqrt(x^2 + y^2) // where we choose the sign so that a exists, and 2ab = y. // Thus 2b^2 = - (x -+ sqrt(x^2 + y^2)). element_init(e0, p->x->field); element_init(e1, e0->field); element_init(e2, e0->field); element_square(e0, p->x); element_square(e1, p->y); element_add(e0, e0, e1); element_sqrt(e0, e0); // e0 = sqrt(x^2 + y^2) element_add(e1, p->x, e0); element_set_si(e2, 2); element_invert(e2, e2); element_mul(e1, e1, e2); // e1 = (x + sqrt(x^2 + y^2))/2 if (!element_is_sqr(e1)) { element_sub(e1, e1, e0); // e1 should be a square. } element_sqrt(e0, e1); element_add(e1, e0, e0); element_invert(e1, e1); element_mul(r->y, p->y, e1); element_set(r->x, e0); element_clear(e0); element_clear(e1); element_clear(e2); }
static val_ptr fun_cmp(val_ptr v[], int(*fun)(int)) { int i = element_cmp(v[0]->elem, v[1]->elem); element_ptr e = (element_ptr)pbc_malloc(sizeof(*e)); element_init(e, M); element_set_si(e, fun(i)); v[0]->elem = e; return v[0]; }
static inline void sn_double_no_check(point_ptr r, point_ptr p) { element_t lambda, e0, e1; element_init(lambda, p->x->field); element_init(e0, p->x->field); element_init(e1, p->x->field); //same point: double them //lambda = (3x^2 + 2x) / 2y element_mul_si(lambda, p->x, 3); element_set_si(e0, 2); element_add(lambda, lambda, e0); element_mul(lambda, lambda, p->x); element_add(e0, p->y, p->y); element_invert(e0, e0); element_mul(lambda, lambda, e0); //x1 = lambda^2 - 2x - 1 element_add(e1, p->x, p->x); element_square(e0, lambda); element_sub(e0, e0, e1); element_set_si(e1, 1); element_sub(e0, e0, e1); //y1 = (x - x1)lambda - y element_sub(e1, p->x, e0); element_mul(e1, e1, lambda); element_sub(e1, e1, p->y); element_set(r->x, e0); element_set(r->y, e1); r->inf_flag = 0; element_clear(lambda); element_clear(e0); element_clear(e1); return; }
void consumerShares(signed long int *codeword){ pairing_t pairing; element_t g, r, a, e_g_g, share; char *argv = "./param/a.param"; char s[16384]; signed long int temp_share; FILE *fp = stdin; fp = fopen(argv, "r"); if (!fp) pbc_die("error opening %s\n", argv); size_t count = fread(s, 1, 16384, fp); if(!count) pbc_die("read parameter failure\n"); fclose(fp); if(pairing_init_set_buf(pairing, s, count)) pbc_die("pairing init failed\n"); if(!pairing_is_symmetric(pairing)) pbc_die("pairing is not symmetric\n"); element_init_G1(g, pairing); element_init_Zr(r, pairing); element_init_Zr(a, pairing); element_init_Zr(share, pairing); element_init_GT(e_g_g, pairing); //find the generator of the group element_set(g, ((curve_data_ptr)((a_pairing_data_ptr) pairing->data)->Eq->data)->gen); element_random(r); element_random(a); //compute e(g, g) element_pairing(e_g_g, g, g); //compute e(g, g)^r element_pow_zn(e_g_g, e_g_g, r); //compute e(g,g)^ra element_pow_zn(e_g_g, e_g_g, a); temp_share = codeword[0]; //transfer signed long int type ecret shares to an element_t type before we do the power of //e_g_g element_set_si(share, temp_share); element_pow_zn(e_g_g, e_g_g, share); }
// Requires j != 0, 1728. void field_init_curve_j(field_ptr f, element_ptr j, mpz_t order, mpz_t cofac) { element_t a, b; element_init(a, j->field); element_init(b, j->field); element_set_si(a, 1728); element_sub(a, a, j); element_invert(a, a); element_mul(a, a, j); //b = 2 j / (1728 - j) element_add(b, a, a); //a = 3 j / (1728 - j) element_add(a, a, b); field_init_curve_ab(f, a, b, order, cofac); element_clear(a); element_clear(b); }
static void fq_sqrt(element_ptr n, element_ptr e) { eptr p = e->data; eptr r = n->data; element_ptr nqr = fq_nqr(n->field); element_t e0, e1, e2; //if (a+b sqrt(nqr))^2 = x+y sqrt(nqr) then //2a^2 = x +- sqrt(x^2 - nqr y^2) //(take the sign which allows a to exist) //and 2ab = y element_init(e0, p->x->field); element_init(e1, e0->field); element_init(e2, e0->field); element_square(e0, p->x); element_square(e1, p->y); element_mul(e1, e1, nqr); element_sub(e0, e0, e1); element_sqrt(e0, e0); //e0 = sqrt(x^2 - nqr y^2) element_add(e1, p->x, e0); element_set_si(e2, 2); element_invert(e2, e2); element_mul(e1, e1, e2); //e1 = (x + sqrt(x^2 - nqr y^2))/2 if (!element_is_sqr(e1)) { element_sub(e1, e1, e0); //e1 should be a square } element_sqrt(e0, e1); element_add(e1, e0, e0); element_invert(e1, e1); element_mul(r->y, p->y, e1); element_set(r->x, e0); element_clear(e0); element_clear(e1); element_clear(e2); }
int main(void) { field_t c; field_t Z19; element_t P, Q, R; mpz_t q, z; element_t a, b; int i; field_t Z19_2; field_t c2; element_t P2, Q2, R2; element_t a2; mpz_init(q); mpz_init(z); mpz_set_ui(q, 19); field_init_fp(Z19, q); element_init(a, Z19); element_init(b, Z19); element_set_si(a, 1); element_set_si(b, 6); mpz_set_ui(q, 18); field_init_curve_ab(c, a, b, q, NULL); element_init(P, c); element_init(Q, c); element_init(R, c); printf("Y^2 = X^3 + X + 6 over F_19\n"); //(0,+/-5) is a generator element_set0(a); curve_from_x(R, a); for (i=1; i<19; i++) { mpz_set_si(z, i); element_mul_mpz(Q, R, z); element_printf("%dR = %B\n", i, Q); } mpz_set_ui(z, 6); element_mul_mpz(P, R, z); //P has order 3 element_printf("P = %B\n", P); for (i=1; i<=3; i++) { mpz_set_si(z, i); element_mul_mpz(Q, R, z); tate_3(a, P, Q, R); element_printf("e_3(P,%dR) = %B\n", i, a); } element_double(P, R); //P has order 9 element_printf("P = %B\n", P); for (i=1; i<=9; i++) { mpz_set_si(z, i); //we're supposed to use multiples of R //but 2R works just as well and it allows us //to use R as the offset every time element_mul_mpz(Q, P, z); tate_9(a, P, Q, R); element_printf("e_9(P,%dP) = %B\n", i, a); } //to do the pairing on all of E(F_19) we need to move to F_19^2 //or compute the rational function explicitly printf("moving to F_19^2\n"); field_init_fi(Z19_2, Z19); //don't need to tell it the real order field_init_curve_ab_map(c2, c, element_field_to_fi, Z19_2, q, NULL); element_init(P2, c2); element_init(Q2, c2); element_init(R2, c2); element_init(a2, Z19_2); element_set0(a2); curve_from_x(P2, a2); element_random(R2); element_printf("P = %B\n", P2); for (i=1; i<=18; i++) { mpz_set_si(z, i); element_mul_mpz(Q2, P2, z); tate_18(a2, P2, Q2, R2, P2); element_printf("e_18(P,%dP) = %B\n", i, a2); } element_clear(P2); element_clear(Q2); element_clear(R2); element_clear(a2); field_clear(c2); field_clear(Z19_2); field_clear(c); element_clear(a); element_clear(b); element_clear(P); element_clear(Q); element_clear(R); field_clear(Z19); mpz_clear(q); mpz_clear(z); return 0; }
static void fq_set_si(element_ptr e, signed long int i) { eptr p = e->data; element_set_si(p->x, i); element_set0(p->y); }
void pbc_param_init_e_gen(pbc_param_t par, int rbits, int qbits) { e_init(par); e_param_ptr p = par->data; //3 takes 2 bits to represent int hbits = (qbits - 2) / 2 - rbits; mpz_ptr q = p->q; mpz_ptr r = p->r; mpz_ptr h = p->h; mpz_t n; field_t Fq; field_t cc; element_t j; int found = 0; //won't find any curves is hbits is too low if (hbits < 3) hbits = 3; mpz_init(n); do { int i; mpz_set_ui(r, 0); if (rand() % 2) { p->exp2 = rbits - 1; p->sign1 = 1; } else { p->exp2 = rbits; p->sign1 = -1; } mpz_setbit(r, p->exp2); p->exp1 = (rand() % (p->exp2 - 1)) + 1; //use q as a temp variable mpz_set_ui(q, 0); mpz_setbit(q, p->exp1); if (p->sign1 > 0) { mpz_add(r, r, q); } else { mpz_sub(r, r, q); } if (rand() % 2) { p->sign0 = 1; mpz_add_ui(r, r, 1); } else { p->sign0 = -1; mpz_sub_ui(r, r, 1); } if (!mpz_probab_prime_p(r, 10)) continue; for (i=0; i<10; i++) { //use q as a temp variable mpz_set_ui(q, 0); mpz_setbit(q, hbits + 1); pbc_mpz_random(h, q); mpz_mul(h, h, h); mpz_mul_ui(h, h, 3); //finally q takes the value it should mpz_mul(n, r, r); mpz_mul(n, n, h); mpz_add_ui(q, n, 1); if (mpz_probab_prime_p(q, 10)) { found = 1; break; } } } while (!found); /* do { mpz_set_ui(r, 0); mpz_setbit(r, rbits); pbc_mpz_random(r, r); mpz_nextprime(r, r); mpz_mul(n, r, r); mpz_mul_ui(n, n, 3); mpz_add_ui(q, n, 1); } while (!mpz_probab_prime_p(q, 10)); */ field_init_fp(Fq, q); element_init(j, Fq); element_set_si(j, 1); field_init_curve_b(cc, j, n, NULL); element_clear(j); // We may need to twist it. { // Pick a random point P and twist the curve if P has the wrong order. element_t P; element_init(P, cc); element_random(P); element_mul_mpz(P, P, n); if (!element_is0(P)) field_reinit_curve_twist(cc); element_clear(P); } element_to_mpz(p->a, curve_field_a_coeff(cc)); element_to_mpz(p->b, curve_field_b_coeff(cc)); mpz_clear(n); }
int main(void) { field_t fp, fx; mpz_t prime; darray_t list; int p = 7; // Exercise poly_is_irred() with a sieve of Erastosthenes for polynomials. darray_init(list); mpz_init(prime); mpz_set_ui(prime, p); field_init_fp(fp, prime); field_init_poly(fx, fp); element_t e; element_init(e, fp); // Enumerate polynomials in F_p[x] up to degree 2. int a[3], d; a[0] = a[1] = a[2] = 0; for(;;) { element_ptr f = pbc_malloc(sizeof(*f)); element_init(f, fx); int j; for(j = 0; j < 3; j++) { element_set_si(e, a[j]); poly_set_coeff(f, e, j); } // Test poly_degree(). for(j = 2; !a[j] && j >= 0; j--); EXPECT(poly_degree(f) == j); // Add monic polynomials to the list. if (j >= 0 && a[j] == 1) darray_append(list, f); else { element_clear(f); free(f); } // Next! d = 0; for(;;) { a[d]++; if (a[d] >= p) { a[d] = 0; d++; if (d > 2) goto break2; } else break; } } break2: ; // Find all composite monic polynomials of degree 3 or less. darray_t prodlist; darray_init(prodlist); void outer(void *data) { element_ptr f = data; void inner(void *data2) { element_ptr g = data2; if (!poly_degree(f) || !poly_degree(g)) return; if (poly_degree(f) + poly_degree(g) > 3) return; element_ptr h = pbc_malloc(sizeof(*h)); element_init(h, fx); element_mul(h, f, g); darray_append(prodlist, h); EXPECT(!poly_is_irred(h)); }
void curve_set_si(element_t R, long int x, long int y) { point_ptr p = (point_ptr)R->data; element_set_si(p->x, x); element_set_si(p->y, y); p->inf_flag = 0; }
// 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); }