void miller(element_t res, mpz_t q, element_t P, element_ptr Qx, element_ptr Qy) { int m; element_t v; element_t Z; element_t a, b, c; element_t t0; element_t e0; const element_ptr cca = curve_a_coeff(P); const element_ptr Px = curve_x_coord(P); const element_ptr Py = curve_y_coord(P); element_ptr Zx, Zy; void do_tangent(void) { // a = -(3 Zx^2 + cc->a) // b = 2 * Zy // c = -(2 Zy^2 + a Zx); element_square(a, Zx); mult1++; element_mul_si(a, a, 3); add1++; add1++; add1++; element_add(a, a, cca); add1++; element_neg(a, a); element_add(b, Zy, Zy); add1++; element_mul(t0, b, Zy); mult1++; element_mul(c, a, Zx); mult1++; element_add(c, c, t0); add1++; element_neg(c, c); d_miller_evalfn(e0, a, b, c, Qx, Qy); element_mul(v, v, e0); multk++; }
/* 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 inline void sn_double_no_check(point_ptr r, point_ptr p) { element_t lambda, e0, e1; element_init(lambda, p->x->field); element_init(e0, p->x->field); element_init(e1, p->x->field); //same point: double them //lambda = (3x^2 + 2x) / 2y element_mul_si(lambda, p->x, 3); element_set_si(e0, 2); element_add(lambda, lambda, e0); element_mul(lambda, lambda, p->x); element_add(e0, p->y, p->y); element_invert(e0, e0); element_mul(lambda, lambda, e0); //x1 = lambda^2 - 2x - 1 element_add(e1, p->x, p->x); element_square(e0, lambda); element_sub(e0, e0, e1); element_set_si(e1, 1); element_sub(e0, e0, e1); //y1 = (x - x1)lambda - y element_sub(e1, p->x, e0); element_mul(e1, e1, lambda); element_sub(e1, e1, p->y); element_set(r->x, e0); element_set(r->y, e1); r->inf_flag = 0; element_clear(lambda); element_clear(e0); element_clear(e1); return; }
static inline void double_no_check(point_ptr r, point_ptr p, element_ptr a) { element_t lambda, e0, e1; field_ptr f = r->x->field; element_init(lambda, f); element_init(e0, f); element_init(e1, f); //lambda = (3x^2 + a) / 2y element_square(lambda, p->x); element_mul_si(lambda, lambda, 3); element_add(lambda, lambda, a); element_double(e0, p->y); element_invert(e0, e0); element_mul(lambda, lambda, e0); //x1 = lambda^2 - 2x //element_add(e1, p->x, p->x); element_double(e1, p->x); element_square(e0, lambda); element_sub(e0, e0, e1); //y1 = (x - x1)lambda - y element_sub(e1, p->x, e0); element_mul(e1, e1, lambda); element_sub(e1, e1, p->y); element_set(r->x, e0); element_set(r->y, e1); r->inf_flag = 0; element_clear(lambda); element_clear(e0); element_clear(e1); return; }
static void fq_mul_si(element_ptr n, element_ptr a, signed long int z) { eptr p = a->data; eptr r = n->data; element_mul_si(r->x, p->x, z); element_mul_si(r->y, p->y, z); }
//compute c_i=a_i+a_i at one time. static void multi_double(element_ptr c[], element_ptr a[], int n) { int i; element_t* table = (element_t*)pbc_malloc(sizeof(element_t)*n); //a big problem? element_t e0, e1, e2; point_ptr q, r; curve_data_ptr cdp = (curve_data_ptr)a[0]->field->data; q = (point_ptr)a[0]->data; element_init(e0,q->y->field); element_init(e1,q->y->field); element_init(e2,q->y->field); for(i=0; i<n; i++){ q = (point_ptr)a[i]->data; r = (point_ptr)c[i]->data; element_init(table[i],q->y->field); if (q->inf_flag) { r->inf_flag = 1; continue; } if (element_is0(q->y)) { r->inf_flag = 1; continue; } } //to compute 1/2y multi. see Cohen's GTM139 Algorithm 10.3.4 for(i=0; i<n; i++){ q = (point_ptr)a[i]->data; element_double(table[i],q->y); if(i>0) element_mul(table[i],table[i],table[i-1]); } element_invert(e2,table[n-1]); //ONLY ONE inv is required now. for(i=n-1; i>0; i--){ q = (point_ptr)a[i]->data; element_mul(table[i],table[i-1],e2); element_mul(e2,e2,q->y); element_double(e2,e2); //e2=e2*2y_j } element_set(table[0],e2); //e2 no longer used. for(i=0; i<n; i++){ q = (point_ptr)a[i]->data; r = (point_ptr)c[i]->data; if(r->inf_flag) continue; //e2=lambda = (3x^2 + a) / 2y element_square(e2, q->x); element_mul_si(e2, e2, 3); element_add(e2, e2, cdp->a); element_mul(e2, e2, table[i]); //Recall that table[i]=1/2y_i //x1 = lambda^2 - 2x element_double(e1, q->x); element_square(e0, e2); element_sub(e0, e0, e1); //y1 = (x - x1)lambda - y element_sub(e1, q->x, e0); element_mul(e1, e1, e2); element_sub(e1, e1, q->y); element_set(r->x, e0); element_set(r->y, e1); r->inf_flag = 0; } element_clear(e0); element_clear(e1); element_clear(e2); for(i=0; i<n; i++){ element_clear(table[i]); } pbc_free(table); }