ecc_point* mult(ecc_point p, mpz_t value){ ecc_point* result ; result =malloc(sizeof(ecc_point)); if (mpz_cmp_ui(value,0)==0) return NULL; if (mpz_cmp_ui(value,1)==0) return (&p); if (mpz_cmp_ui(value,2)==0) return double_p(p); mpz_t aux,aux1; mpz_init_set(aux,value); mpz_init_set(aux1,value); if (mpz_cmp_ui(aux,0)!=0){ mpz_mod_ui(aux,aux,2); if (mpz_cmp_ui(aux,0) != 0 ){ mpz_sub_ui(aux1,aux1,1); result = sum(p, (*mult(p,aux1))); }else{ mpz_set(aux,value); mpz_div_ui(aux1,aux1,2); result = double_p((*mult(p,aux1))); } } return result; }
ecc_point* sum(ecc_point p1,ecc_point p2){ ecc_point* result; result = malloc(sizeof(ecc_point)); mpz_init((*result).x); mpz_init((*result).y); if (mpz_cmp(p1.x,p2.x)==0 && mpz_cmp(p1.y,p2.y)==0) result=double_p(p1); else if( mpz_cmp(p1.x,p2.x)==0 && mpz_cmpabs(p2.y,p1.y)==0) result=INFINITY_POINT; else{ mpz_t delta_x,x,y,delta_y,s,s_2; mpz_init(delta_x); mpz_init(x); mpz_init(y); mpz_init(s); mpz_init(s_2); mpz_init(delta_y); mpz_sub(delta_x,p1.x,p2.x); mpz_sub(delta_y,p1.y,p2.y); mpz_mod(delta_x,delta_x,prime); mpz_invert(delta_x,delta_x,prime); mpz_mul(s,delta_x,delta_y); mpz_mod(s,s,prime); mpz_pow_ui(s_2,s,2); mpz_sub(x,s_2,p1.x); mpz_sub(x,x,p2.x); mpz_mod(x,x,prime); mpz_set((*result).x,x); mpz_sub(delta_x,p2.x,x); mpz_neg(y,p2.y); mpz_addmul(y,s,delta_x); mpz_mod(y,y,prime); mpz_set((*result).y,y); }; return result; }
double get(int i, int j, int k) const { return swap(*double_p(data(i, j, k))); }
void put(int i, int j, int k, double d) { *double_p(data(i, j, k)) = swap(d); }