static inline void fib_matrix_mul (mpz_t a, mpz_t b, mpz_t c, mpz_t d, mpz_t e, mpz_t f, mpz_t g, mpz_t h) { mpz_t r, s, t, u; mpz_init (r); mpz_init (s); mpz_init (t); mpz_init (u); mpz_mul (r, a, e); mpz_mul (s, a, f); mpz_mul (t, c, e); mpz_mul (u, c, f); mpz_addmul (r, b, g); mpz_addmul (s, b, h); mpz_addmul (t, d, g); mpz_addmul (u, d, h); mpz_set (a, r); mpz_set (b, s); mpz_set (c, t); mpz_set (d, u); mpz_clear (r); mpz_clear (s); mpz_clear (t); mpz_clear (u); }
/*-------------------------------------------------------------------*/ static void convert_to_integer(mpz_poly_t *alg_sqrt, mpz_t n, mpz_t c, mpz_t m1, mpz_t m0, mpz_t res) { /* given the completed square root, apply the homomorphism to convert the polynomial to an integer. We do this by evaluating alg_sqrt at -c*m0/m1, with all calculations performed mod n */ uint32 i; mpz_t m1_pow; mpz_t m0c; mpz_init_set(m1_pow, m1); mpz_poly_mod_q(alg_sqrt, n, alg_sqrt); mpz_init_set_ui(m0c, 0); mpz_submul(m0c, m0, c); mpz_mod(m0c, m0c, n); i = alg_sqrt->degree; mpz_set(res, alg_sqrt->coeff[i]); while (--i) { mpz_mul(res, res, m0c); mpz_addmul(res, m1_pow, alg_sqrt->coeff[i]); mpz_mul(m1_pow, m1_pow, m1); } mpz_mul(res, res, m0c); mpz_addmul(res, m1_pow, alg_sqrt->coeff[i]); mpz_mod(res, res, n); mpz_clear(m1_pow); mpz_clear(m0c); }
static int hgcd_ref (struct hgcd_ref *hgcd, mpz_t a, mpz_t b) { mp_size_t n = MAX (mpz_size (a), mpz_size (b)); mp_size_t s = n/2 + 1; mpz_t q; int res; if (mpz_size (a) <= s || mpz_size (b) <= s) return 0; res = mpz_cmp (a, b); if (res < 0) { mpz_sub (b, b, a); if (mpz_size (b) <= s) return 0; mpz_set_ui (hgcd->m[0][0], 1); mpz_set_ui (hgcd->m[0][1], 0); mpz_set_ui (hgcd->m[1][0], 1); mpz_set_ui (hgcd->m[1][1], 1); } else if (res > 0) { mpz_sub (a, a, b); if (mpz_size (a) <= s) return 0; mpz_set_ui (hgcd->m[0][0], 1); mpz_set_ui (hgcd->m[0][1], 1); mpz_set_ui (hgcd->m[1][0], 0); mpz_set_ui (hgcd->m[1][1], 1); } else return 0; mpz_init (q); for (;;) { ASSERT (mpz_size (a) > s); ASSERT (mpz_size (b) > s); if (mpz_cmp (a, b) > 0) { if (!sdiv_qr (q, a, s, a, b)) break; mpz_addmul (hgcd->m[0][1], q, hgcd->m[0][0]); mpz_addmul (hgcd->m[1][1], q, hgcd->m[1][0]); } else { if (!sdiv_qr (q, b, s, b, a)) break; mpz_addmul (hgcd->m[0][0], q, hgcd->m[0][1]); mpz_addmul (hgcd->m[1][0], q, hgcd->m[1][1]); } } mpz_clear (q); return 1; }
ecc_point* existPoint(mpz_t p){ mpz_t l; mpz_init(l); mpz_pow_ui(l,p,3); mpz_addmul(l,a,p); mpz_add(l,l,b); mpz_mod(l,l,prime); mpz_t i; mpz_init_set_ui(i,0); mpz_t y; mpz_init(y); if (quadratic_residue(y,l,prime)==1){ gmp_printf("entrei"); ecc_point* r= malloc(sizeof(ecc_point)); mpz_init_set((*r).x,p); mpz_init_set((*r).y,y); return r; } else return NULL; /* while(mpz_cmp(i,prime)!=0){ mpz_set(y,i); mpz_pow_ui(y,y,2); mpz_mod(y,y,prime); gmp_printf(" x %Zd Y %Zd \n",l,y); if (mpz_cmp(y,l)==0){ ecc_point* r= malloc(sizeof(ecc_point)); mpz_init_set((*r).x,p); mpz_init_set((*r).y,i); return r; }else mpz_add_ui(i,i,1); }*/ return NULL; }
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; }
/*------------------------------------------------------------------------*/ static uint32 lift_roots(sieve_fb_t *s, curr_poly_t *c, uint64 p, uint32 num_roots) { uint32 i; uint32 degree = s->degree; uint64_2gmp(p, s->p); mpz_mul(s->p2, s->p, s->p); mpz_tdiv_r(s->nmodp2, c->trans_N, s->p2); mpz_sub(s->tmp1, c->trans_m0, c->mp_sieve_size); mpz_tdiv_r(s->m0, s->tmp1, s->p2); for (i = 0; i < num_roots; i++) { mpz_powm_ui(s->tmp1, s->roots[i], (mp_limb_t)degree, s->p2); mpz_sub(s->tmp1, s->nmodp2, s->tmp1); if (mpz_cmp_ui(s->tmp1, (mp_limb_t)0) < 0) mpz_add(s->tmp1, s->tmp1, s->p2); mpz_tdiv_q(s->tmp1, s->tmp1, s->p); mpz_powm_ui(s->tmp2, s->roots[i], (mp_limb_t)(degree-1), s->p); mpz_mul_ui(s->tmp2, s->tmp2, (mp_limb_t)degree); mpz_invert(s->tmp2, s->tmp2, s->p); mpz_mul(s->tmp1, s->tmp1, s->tmp2); mpz_tdiv_r(s->tmp1, s->tmp1, s->p); mpz_addmul(s->roots[i], s->tmp1, s->p); mpz_sub(s->roots[i], s->roots[i], s->m0); if (mpz_cmp_ui(s->roots[i], (mp_limb_t)0) < 0) mpz_add(s->roots[i], s->roots[i], s->p2); } return num_roots; }
/* multiplies b[0]+...+b[k-1]*x^(k-1)+x^k by c[0]+...+c[l-1]*x^(l-1)+x^l and puts the results in a[0]+...+a[k+l-1]*x^(k+l-1) [the leading monomial x^(k+l) is implicit]. If monic_b (resp. monic_c) is 0, don't consider x^k in b (resp. x^l in c). Assumes k = l or k = l+1. The auxiliary array t contains at least list_mul_mem(l) entries. a and t should not overlap. */ void list_mul (listz_t a, listz_t b, unsigned int k, int monic_b, listz_t c, unsigned int l, int monic_c, listz_t t) { unsigned int i, po2; ASSERT(k == l || k == l + 1); for (po2 = l; (po2 & 1) == 0; po2 >>= 1); po2 = (po2 == 1); #ifdef DEBUG if (Fermat && !(po2 && l == k)) fprintf (ECM_STDOUT, "list_mul: Fermat number, but poly lengths %d and %d\n", k, l); #endif if (po2 && Fermat) { if (monic_b && monic_c && l == k) { F_mul (a, b, c, l, MONIC, Fermat, t); monic_b = monic_c = 0; } else F_mul (a, b, c, l, DEFAULT, Fermat, t); } else LIST_MULT_N (a, b, c, l, t); /* set a[0]...a[2l-2] */ if (k > l) /* multiply b[l]*x^l by c[0]+...+c[l-1]*x^(l-1) */ { for (i = 0; i < l - 1; i++) mpz_addmul (a[l+i], b[l], c[i]); mpz_mul (a[2*l-1], b[l], c[l-1]); } /* deal with x^k and x^l */ if (monic_b || monic_c) { mpz_set_ui (a[k + l - 1], 0); if (monic_b && monic_c) /* Single pass over a[] */ { /* a += b * x^l + c * x^k, so a[i] += b[i-l]; a[i] += c[i-k] if 0 <= i-l < k or 0 <= i-k < l, respectively */ if (k > l) mpz_add (a[l], a[l], b[0]); for (i = k; i < k + l; i++) { mpz_add (a[i], a[i], b[i-l]); /* i-l < k */ mpz_add (a[i], a[i], c[i-k]); /* i-k < l */ } } else if (monic_c) /* add b * x^l */ list_add (a + l, a + l, b, k); else /* only monic_b, add x^k * c */ list_add (a + k, a + k, c, l); } }
// sign a hash using ECDSA, hash must be a string in base used during initialisation. // private key and a generator point are required for it to work (look SetDomain // and SetKeys) void ECDSA::Sign( char *hash, char *&r, char *&s ) { mpz_t z,k,rr,ss,t,u; ECPoint kG; mpz_init_set_str(z, hash, m_base); mpz_inits(k, rr, ss, t, u, NULL); do { mpz_urandomm(k, m_st, ecc->m_n); ecc->MultiplePoint(k, ecc->m_G, kG); mpz_set(rr, kG.x); mpz_mod(rr, rr, ecc->m_n); } while (!mpz_cmp_ui(rr, 0)); do { mpz_set(t,z); mpz_addmul(t,rr,ecc->m_dA); mpz_set(u,k); mpz_invert(u,u,ecc->m_n); mpz_mul(ss, t, u); mpz_mod(ss, ss, ecc->m_n); } while (!mpz_cmp_ui(ss, 0)); mpz_get_str(r, m_base, rr); mpz_get_str(s, m_base, ss); mpz_clears(z,k,rr,ss,t,u,NULL); return; }
int sign_quad() { // Returns sign of c0 z^2 - 2 a0 z - b0 mpz_mul_si(t0, p->a0, -2); mpz_addmul(t0, p->c0, z); mpz_mul(t0, t0, z); mpz_sub(t0, t0, p->b0); return mpz_sgn(t0); }
int sign_quad1() { // Returns sign of c1 z^2 - 2 a1 z - b1 mpz_mul_si(t0, p->a1, -2); mpz_addmul(t0, p->c1, z); mpz_mul(t0, t0, z); mpz_sub(t0, t0, p->b1); return mpz_sgn(t0); }
void refmpq_add (mpq_ptr w, mpq_srcptr x, mpq_srcptr y) { mpz_mul (mpq_numref(w), mpq_numref(x), mpq_denref(y)); mpz_addmul (mpq_numref(w), mpq_denref(x), mpq_numref(y)); mpz_mul (mpq_denref(w), mpq_denref(x), mpq_denref(y)); mpq_canonicalize (w); }
/* puts in a[K-1]..a[2K-2] the K high terms of the product of b[0..K-1] and c[0..K-1]. Assumes K >= 1, and a[0..2K-2] exist. Needs space for list_mul_mem(K) in t. */ void list_mul_high (listz_t a, listz_t b, listz_t c, unsigned int K, listz_t t) { #ifdef KS_MULTIPLY /* ks is faster */ LIST_MULT_N (a, b, c, K, t); #else unsigned int p, q; ASSERT(K > 0); switch (K) { case 1: mpz_mul (a[0], b[0], c[0]); return; case 2: mpz_mul (a[2], b[1], c[1]); mpz_mul (a[1], b[1], c[0]); mpz_addmul (a[1], b[0], c[1]); return; case 3: karatsuba (a + 2, b + 1, c + 1, 2, t); mpz_addmul (a[2], b[0], c[2]); mpz_addmul (a[2], b[2], c[0]); return; default: /* MULT is 2 for Karatsuba, 3 for Toom3, 4 for Toom4 */ for (p = 1; MULT * p <= K; p *= MULT); p = (K / p) * p; q = K - p; LIST_MULT_N (a + 2 * q, b + q, c + q, p, t); if (q) { list_mul_high (t, b + p, c, q, t + 2 * q - 1); list_add (a + K - 1, a + K - 1, t + q - 1, q); list_mul_high (t, c + p, b, q, t + 2 * q - 1); list_add (a + K - 1, a + K - 1, t + q - 1, q); } } #endif }
/** * Multiplies two polynomials with appropriate mod where their coefficients are indexed into the array. */ void polymul(mpz_t* rop, mpz_t* op1, unsigned int len1, mpz_t* op2, unsigned int len2, mpz_t n) { int i, j, t; for (i = 0; i < len1; i++) { for (j = 0; j < len2; j++) { t = (i + j) % len1; mpz_addmul(rop[t], op1[i], op2[j]); mpz_mod(rop[t], rop[t], n); } } }
void poly_mod_sqr(mpz_t* px, mpz_t* ptmp, UV r, mpz_t mod) { UV i, d, s; UV degree = r-1; for (i = 0; i < r; i++) mpz_set_ui(ptmp[i], 0); for (d = 0; d <= 2*degree; d++) { UV prindex = d % r; for (s = (d <= degree) ? 0 : d-degree; s <= (d/2); s++) { if (s*2 == d) { mpz_addmul( ptmp[prindex], px[s], px[s] ); } else { mpz_addmul( ptmp[prindex], px[s], px[d-s] ); mpz_addmul( ptmp[prindex], px[s], px[d-s] ); } } } /* Put ptmp into px and mod n */ for (i = 0; i < r; i++) mpz_mod(px[i], ptmp[i], mod); }
/* puts in a[0]..a[K-1] the K low terms of the product of b[0..K-1] and c[0..K-1]. Assumes K >= 1, and a[0..2K-2] exist. Needs space for list_mul_mem(K) in t. */ static void list_mul_low (listz_t a, listz_t b, listz_t c, unsigned int K, listz_t t, mpz_t n) { unsigned int p, q; ASSERT(K > 0); switch (K) { case 1: mpz_mul (a[0], b[0], c[0]); return; case 2: mpz_mul (a[0], b[0], c[0]); mpz_mul (a[1], b[0], c[1]); mpz_addmul (a[1], b[1], c[0]); return; case 3: karatsuba (a, b, c, 2, t); mpz_addmul (a[2], b[2], c[0]); mpz_addmul (a[2], b[0], c[2]); return; default: /* MULT is 2 for Karatsuba, 3 for Toom3, 4 for Toom4 */ for (p = 1; MULT * p <= K; p *= MULT); /* p = greatest power of MULT <=K */ p = (K / p) * p; ASSERTD(list_check(b,p,n) && list_check(c,p,n)); LIST_MULT_N (a, b, c, p, t); if ((q = K - p)) { list_mul_low (t, b + p, c, q, t + 2 * q - 1, n); list_add (a + p, a + p, t, q); list_mul_low (t, c + p, b, q, t + 2 * q - 1, n); list_add (a + p, a + p, t, q); } } }
int existPoint1(mpz_t x, mpz_t y){ mpz_t exp,eq_result; mpz_init(eq_result); //Equation Result mpz_init(exp); //Exponentiation Result mpz_pow_ui(exp,x,3); mpz_addmul(exp,x,a); mpz_add(exp,exp,b); gmp_printf("%Zd x \n",exp); mpz_mod(exp,exp,prime); mpz_pow_ui(eq_result,y,2); mpz_mod(eq_result,eq_result,prime); if (mpz_cmp(eq_result,exp)==0) return 1; else return 0; }
void test_ext_gcd() { const char *list[][3] = { {"2","3","1"}, {"2","4","2"}, {"20","40","20"}, {"-20","31","1"}, {"-20","-30","10"} }; int n = sizeof(list)/sizeof(list[0]); int correct = 0; test_info(stderr,"Start testing ext_gcd."); for(int i = 0; i < n; i++) { mpz_t a,b,c,d,e,f; mpz_init_set_str(a,list[i][0],10); mpz_init_set_str(b,list[i][1],10); mpz_init_set_str(c,list[i][2],10); mpz_init(d); mpz_init(e); mpz_init(f); cpt_ext_gcd(d,e,f,a,b); if(mpz_cmp(c,d)!=0) { test_unmatch(stderr,"test_ext_gcd",c,d); } else { mpz_mul(d,e,a); mpz_addmul(d,f,b); if(mpz_cmp(c,d)!=0) test_unmatch(stderr,"test_ext_gcd",c,d); else correct++; } mpz_clear(a); mpz_clear(b); mpz_clear(c); mpz_clear(d); mpz_clear(e); mpz_clear(f); } if(correct == n) test_info(stderr,"test_ext_gcd success."); else test_info(stderr,"test_ext_gcd failed."); }
//All our byte arrays are supposed to be little endian. static void ecdsa_sign(unsigned char signature[96], const unsigned char digest[48], const unsigned char keyb[48]){ unsigned char kbuf[96]; unsigned char kexp[48]; unsigned char point[96]; for(int i=0; i<48; i++){ kexp[i]=0; } mpz_t order; mpz_t k; mpz_t kinv; mpz_t x; //x coordinate mpz_t d; //digest mpz_t key; //key mpz_init(order); mpz_init(k); mpz_init(x); mpz_init(d); mpz_init(key); mpz_init(kinv); mpz_set_str(order, "39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643", 10); randombytes(kbuf, 96); mpz_import(k, 96, -1, 1, 1, 0, kbuf); mpz_mod(k, k, order); mpz_export(kexp, NULL, -1, 1, 1, 0, k); p384_32_scalarmult_base(point, kexp); mpz_import(x, 48, 1, 1, 1, 0, point); mpz_mod(x, x, order); mpz_import(d, 48, -1, 1, 1, 0, digest); mpz_import(key, 48, -1, 1, 1, 0, keyb); mpz_invert(kinv, k, order); mpz_addmul(d, x, key); mpz_mod(d, d, order); mpz_mul(d, kinv, d); mpz_mod(d, d, order); for(int i=0; i<96; i++){ signature[i]=0; } mpz_export(signature, NULL, -1, 1, 1, 0, x); mpz_export(signature+48, NULL, -1, 1, 1, 0, d); mpz_clear(order); mpz_clear(k); mpz_clear(kinv); mpz_clear(x); mpz_clear(d); mpz_clear(key); }
void testmain (int argc, char **argv) { unsigned i; mpz_t a, b, res, ref; mpz_init (a); mpz_init (b); mpz_init_set_ui (res, 5); mpz_init (ref); for (i = 0; i < COUNT; i++) { mini_random_op3 (OP_MUL, MAXBITS, a, b, ref); if (i & 1) { mpz_add (ref, ref, res); if (mpz_fits_ulong_p (b)) mpz_addmul_ui (res, a, mpz_get_ui (b)); else mpz_addmul (res, a, b); } else { mpz_sub (ref, res, ref); if (mpz_fits_ulong_p (b)) mpz_submul_ui (res, a, mpz_get_ui (b)); else mpz_submul (res, a, b); } if (mpz_cmp (res, ref)) { if (i & 1) fprintf (stderr, "mpz_addmul failed:\n"); else fprintf (stderr, "mpz_submul failed:\n"); dump ("a", a); dump ("b", b); dump ("r", res); dump ("ref", ref); abort (); } } mpz_clear (a); mpz_clear (b); mpz_clear (res); mpz_clear (ref); }
/* Simple polynomial multiplication */ void poly_mod_mul(mpz_t* px, mpz_t* py, mpz_t* ptmp, UV r, mpz_t mod) { UV i, j, prindex; for (i = 0; i < r; i++) mpz_set_ui(ptmp[i], 0); for (i = 0; i < r; i++) { if (!mpz_sgn(px[i])) continue; for (j = 0; j < r; j++) { if (!mpz_sgn(py[j])) continue; prindex = (i+j) % r; mpz_addmul( ptmp[prindex], px[i], py[j] ); } } /* Put ptmp into px and mod n */ for (i = 0; i < r; i++) mpz_mod(px[i], ptmp[i], mod); }
/* assuming b[0]...b[2(n-1)] are computed, computes and stores B[2n]*(2n+1)! t/(exp(t)-1) = sum(B[j]*t^j/j!, j=0..infinity) thus t = (exp(t)-1) * sum(B[j]*t^j/j!, n=0..infinity). Taking the coefficient of degree n+1 > 1, we get: 0 = sum(1/(n+1-k)!*B[k]/k!, k=0..n) which gives: B[n] = -sum(binomial(n+1,k)*B[k], k=0..n-1)/(n+1). Let C[n] = B[n]*(n+1)!. Then C[n] = -sum(binomial(n+1,k)*C[k]*n!/(k+1)!, k=0..n-1), which proves that the C[n] are integers. */ mpz_t* mpfr_bernoulli_internal (mpz_t *b, unsigned long n) { if (n == 0) { b = (mpz_t *) (*__gmp_allocate_func) (sizeof (mpz_t)); mpz_init_set_ui (b[0], 1); } else { mpz_t t; unsigned long k; b = (mpz_t *) (*__gmp_reallocate_func) (b, n * sizeof (mpz_t), (n + 1) * sizeof (mpz_t)); mpz_init (b[n]); /* b[n] = -sum(binomial(2n+1,2k)*C[k]*(2n)!/(2k+1)!, k=0..n-1) */ mpz_init_set_ui (t, 2 * n + 1); mpz_mul_ui (t, t, 2 * n - 1); mpz_mul_ui (t, t, 2 * n); mpz_mul_ui (t, t, n); mpz_fdiv_q_ui (t, t, 3); /* exact: t=binomial(2*n+1,2*k)*(2*n)!/(2*k+1)! for k=n-1 */ mpz_mul (b[n], t, b[n-1]); for (k = n - 1; k-- > 0;) { mpz_mul_ui (t, t, 2 * k + 1); mpz_mul_ui (t, t, 2 * k + 2); mpz_mul_ui (t, t, 2 * k + 2); mpz_mul_ui (t, t, 2 * k + 3); mpz_fdiv_q_ui (t, t, 2 * (n - k) + 1); mpz_fdiv_q_ui (t, t, 2 * (n - k)); mpz_addmul (b[n], t, b[k]); } /* take into account C[1] */ mpz_mul_ui (t, t, 2 * n + 1); mpz_fdiv_q_2exp (t, t, 1); mpz_sub (b[n], b[n], t); mpz_neg (b[n], b[n]); mpz_clear (t); } return b; }
/* Return non-zero iff c+i*d is an exact square (a+i*b)^2, with a, b both of the form m*2^e with m, e integers. If so, returns in a+i*b the corresponding square root, with a >= 0. The variables a, b must not overlap with c, d. We have c = a^2 - b^2 and d = 2*a*b. If one of a, b is exact, then both are (see algorithms.tex). Case 1: a <> 0 and b <> 0. Let a = m*2^e and b = n*2^f with m, e, n, f integers, m and n odd (we will treat apart the case a = 0 or b = 0). Then 2*a*b = m*n*2^(e+f+1), thus necessarily e+f >= -1. Assume e < 0, then f >= 0, then a^2 - b^2 = m^2*2^(2e) - n^2*2^(2f) cannot be an integer, since n^2*2^(2f) is an integer, and m^2*2^(2e) is not. Similarly when f < 0 (and thus e >= 0). Thus we have e, f >= 0, and a, b are both integers. Let A = 2a^2, then eliminating b between c = a^2 - b^2 and d = 2*a*b gives A^2 - 2c*A - d^2 = 0, which has solutions c +/- sqrt(c^2+d^2). We thus need c^2+d^2 to be a square, and c + sqrt(c^2+d^2) --- the solution we are interested in --- to be two times a square. Then b = d/(2a) is necessarily an integer. Case 2: a = 0. Then d is necessarily zero, thus it suffices to check whether c = -b^2, i.e., if -c is a square. Case 3: b = 0. Then d is necessarily zero, thus it suffices to check whether c = a^2, i.e., if c is a square. */ static int mpc_perfect_square_p (mpz_t a, mpz_t b, mpz_t c, mpz_t d) { if (mpz_cmp_ui (d, 0) == 0) /* case a = 0 or b = 0 */ { /* necessarily c < 0 here, since we have already considered the case where x is real non-negative and y is real */ MPC_ASSERT (mpz_cmp_ui (c, 0) < 0); mpz_neg (b, c); if (mpz_perfect_square_p (b)) /* case 2 above */ { mpz_sqrt (b, b); mpz_set_ui (a, 0); return 1; /* c + i*d = (0 + i*b)^2 */ } } else /* both a and b are non-zero */ { if (mpz_divisible_2exp_p (d, 1) == 0) return 0; /* d must be even */ mpz_mul (a, c, c); mpz_addmul (a, d, d); /* c^2 + d^2 */ if (mpz_perfect_square_p (a)) { mpz_sqrt (a, a); mpz_add (a, c, a); /* c + sqrt(c^2+d^2) */ if (mpz_divisible_2exp_p (a, 1)) { mpz_tdiv_q_2exp (a, a, 1); if (mpz_perfect_square_p (a)) { mpz_sqrt (a, a); mpz_tdiv_q_2exp (b, d, 1); /* d/2 */ mpz_divexact (b, b, a); /* d/(2a) */ return 1; } } } } return 0; /* not a square */ }
/*-------------------------------------------------------------------------*/ static uint32 check_poly(curr_poly_t *c, mpz_t *coeffs, mpz_t lin0, mpz_t gmp_N, uint32 degree) { uint32 i; mpz_set(c->gmp_help1, coeffs[degree]); mpz_set(c->gmp_help2, c->gmp_p); for (i = degree; i; i--) { mpz_mul(c->gmp_help1, c->gmp_help1, lin0); mpz_neg(c->gmp_help1, c->gmp_help1); mpz_addmul(c->gmp_help1, coeffs[i-1], c->gmp_help2); mpz_mul(c->gmp_help2, c->gmp_help2, c->gmp_p); } mpz_tdiv_r(c->gmp_help1, c->gmp_help1, gmp_N); if (mpz_cmp_ui(c->gmp_help1, (mp_limb_t)0) != 0) { printf("error: corrupt polynomial expand\n"); return 0; } return 1; }
static void dot_product_enc(Crypto *c, mpz_t dp, const mpz_t *a, const mpz_t *b, int size) { mpz_t temp, p; mpz_init_set_ui(temp, 0); mpz_init_set_ui(p, 0); mpz_set_ui(dp, 0); for (int i = 0; i < size; i++) { mpz_addmul(dp, a[i], b[i]); //mpz_add(dp, dp, temp); } c->elgamal_get_public_modulus(&p); mpz_sub_ui(p, p, 1); mpz_mod(dp, dp, p); encode_plain(c, dp, dp); mpz_clear(temp); mpz_clear(p); }
/*------------------------------------------------------------------------*/ static void lift_roots(sieve_fb_t *s, poly_coeff_t *c, uint32 p, uint32 num_roots) { /* we have num_roots arithmetic progressions mod p; convert the progressions to be mod p^2, using Hensel lifting, and then move the origin of the result trans_m0 units to the left. */ uint32 i; unsigned long degree = s->degree; mpz_set_ui(s->p, (unsigned long)p); mpz_mul(s->pp, s->p, s->p); mpz_tdiv_r(s->nmodpp, c->trans_N, s->pp); mpz_tdiv_r(s->tmp3, c->trans_m0, s->pp); for (i = 0; i < num_roots; i++) { uint64_2gmp(s->roots[i], s->gmp_root); mpz_powm_ui(s->tmp1, s->gmp_root, degree, s->pp); mpz_sub(s->tmp1, s->nmodpp, s->tmp1); if (mpz_cmp_ui(s->tmp1, (mp_limb_t)0) < 0) mpz_add(s->tmp1, s->tmp1, s->pp); mpz_tdiv_q(s->tmp1, s->tmp1, s->p); mpz_powm_ui(s->tmp2, s->gmp_root, degree-1, s->p); mpz_mul_ui(s->tmp2, s->tmp2, degree); mpz_invert(s->tmp2, s->tmp2, s->p); mpz_mul(s->tmp1, s->tmp1, s->tmp2); mpz_tdiv_r(s->tmp1, s->tmp1, s->p); mpz_addmul(s->gmp_root, s->tmp1, s->p); mpz_sub(s->gmp_root, s->gmp_root, s->tmp3); if (mpz_cmp_ui(s->gmp_root, (unsigned long)0) < 0) mpz_add(s->gmp_root, s->gmp_root, s->pp); s->roots[i] = gmp2uint64(s->gmp_root); } }
void check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y) { mpz_t want, got; mpz_init (want); mpz_init (got); mpz_mul (want, x, y); mpz_add (want, w, want); mpz_set (got, w); mpz_addmul (got, x, y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_addmul fail\n"); fail: mpz_trace ("w", w); mpz_trace ("x", x); mpz_trace ("y", y); mpz_trace ("want", want); mpz_trace ("got ", got); abort (); } mpz_mul (want, x, y); mpz_sub (want, w, want); mpz_set (got, w); mpz_submul (got, x, y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_submul fail\n"); goto fail; } mpz_clear (want); mpz_clear (got); }
void sieve_xy_run_deg6(root_sieve_t *rs) { uint32 i; sieve_xyz_t *xyz = &rs->xyzdata; int64 z_base = xyz->z_base; sieve_xy_t *xy = &rs->xydata; sieve_prime_t *lattice_primes = xy->lattice_primes; uint32 num_lattice_primes; msieve_obj *obj = rs->data->obj; double direction[3] = {0, 1, 0}; double line_min, line_max; uint16 cutoff_score; xydata_t xydata[MAX_CRT_FACTORS]; plane_heap_t plane_heap; uint64 inv_xy; uint64 inv_xyz; compute_line_size(rs->max_norm, &rs->apoly, rs->dbl_p, rs->dbl_d, direction, -10000, 10000, &line_min, &line_max); if (line_min > line_max) return; num_lattice_primes = xy->num_lattice_primes = find_lattice_primes(rs->primes, rs->num_primes, xyz->lattice_size, lattice_primes, &xy->lattice_size, line_max - line_min); inv_xy = mp_modinv_2(xyz->lattice_size, xy->lattice_size); inv_xyz = mp_modinv_2(xy->lattice_size, xyz->lattice_size); uint64_2gmp(xy->lattice_size, xy->tmp1); uint64_2gmp(inv_xy, xy->tmp2); uint64_2gmp(xyz->lattice_size, xy->tmp3); uint64_2gmp(inv_xyz, xy->tmp4); mpz_mul(xy->mp_lattice_size, xy->tmp1, xy->tmp3); mpz_mul(xy->crt0, xy->tmp2, xy->tmp3); mpz_mul(xy->crt1, xy->tmp1, xy->tmp4); xy->dbl_lattice_size = mpz_get_d(xy->mp_lattice_size); xydata_alloc(lattice_primes, num_lattice_primes, xyz->lattice_size, xydata); plane_heap.num_entries = 0; for (i = 0; i < xyz->num_lattices; i++) { lattice_t *curr_lattice_xyz = xyz->lattices + i; xydata_init(xydata, num_lattice_primes, curr_lattice_xyz, z_base); find_hits(rs, xydata, num_lattice_primes, i, &plane_heap); } xydata_free(xydata, num_lattice_primes); qsort(plane_heap.entries, plane_heap.num_entries, sizeof(plane_t), compare_planes); cutoff_score = 0.9 * plane_heap.entries[0].plane.score; for (i = 0; i < plane_heap.num_entries; i++) { plane_t *curr_plane = plane_heap.entries + i; lattice_t *lattice_xy = &curr_plane->plane; lattice_t *lattice_xyz = xyz->lattices + curr_plane->which_lattice_xyz; if (lattice_xy->score < cutoff_score) break; line_min = xyz->y_line_min[curr_plane->which_z_block]; line_max = xyz->y_line_max[curr_plane->which_z_block]; z_base = xyz->z_base + curr_plane->which_z_block * xyz->lattice_size; xy->apoly = rs->apoly; xy->apoly.coeff[3] += z_base * rs->dbl_p; xy->apoly.coeff[2] -= z_base * rs->dbl_d; mpz_set_d(xy->tmp1, line_min); mpz_tdiv_q(xy->y_base, xy->tmp1, xy->mp_lattice_size); mpz_mul(xy->y_base, xy->y_base, xy->mp_lattice_size); xy->y_blocks = (line_max - line_min) / xy->dbl_lattice_size; uint64_2gmp(lattice_xy->x, xy->tmp1); uint64_2gmp(lattice_xyz->x, xy->tmp2); mpz_mul(xy->resclass_x, xy->tmp1, xy->crt0); mpz_addmul(xy->resclass_x, xy->tmp2, xy->crt1); uint64_2gmp(lattice_xy->y, xy->tmp1); uint64_2gmp(lattice_xyz->y, xy->tmp2); mpz_mul(xy->resclass_y, xy->tmp1, xy->crt0); mpz_addmul(xy->resclass_y, xy->tmp2, xy->crt1); mpz_tdiv_r(xy->resclass_x, xy->resclass_x, xy->mp_lattice_size); mpz_tdiv_r(xy->resclass_y, xy->resclass_y, xy->mp_lattice_size); xy->curr_score = lattice_xyz->score + lattice_xy->score; rs->curr_z = z_base + lattice_xyz->z; sieve_x_run_deg6(rs); if (obj->flags & MSIEVE_FLAG_STOP_SIEVING) break; } }
bool CMTSumCheckVerifier:: doFinalCheck(CMTSumCheckResults& results, const MPZVector& expected) { mpz_t add_predr, mul_predr, fz, betar; mpz_init(add_predr); mpz_init(mul_predr); mpz_init(betar); mpz_init(fz); requestVs(results.Vs); int mi = outLayer.logSize(); int ni = outLayer.size(); int mip1 = inLayer.logSize(); int nip1 = inLayer.size(); results.setupTime.begin_with_history(); outLayer.computeWirePredicates(add_predr, mul_predr, results.rand, nip1, prime); //outLayer.add_fn(predr, results.rand.raw_vec(), mi, mip1, ni, nip1, prime); //outLayer.mul_fn(predr, results.rand.raw_vec(), mi, mip1, ni, nip1, prime); evaluate_beta(betar, z.raw_vec(), results.rand.raw_vec(), mi, prime); results.setupTime.end(); // DEBUG //gmp_printf("[V] betar: %Zd\n", tmp); results.totalCheckTime.begin_with_history(); bool success = true; #ifndef CMTGKR_DISABLE_CHECKS for (int b = 0; b < conf.batchSize(); b++) { mpz_set_ui(fz, 0); mpz_add(tmp, results.Vs[2 * b], results.Vs[2 * b + 1]); mpz_addmul(fz, tmp, add_predr); mpz_mul(tmp, results.Vs[2 * b], results.Vs[2 * b + 1]); mpz_addmul(fz, tmp, mul_predr); modmult(fz, fz, betar, prime); success = mpz_cmp(expected[b], fz) == 0; if (!success) { cout << "[Instance " << b << "] [SumCheck] Final check failed!" << endl; gmp_printf("fz is: %Zd\n", fz); gmp_printf("expected is: %Zd\n", expected[b]); cout << endl; break; } } #endif results.totalCheckTime.end(); mpz_clear(add_predr); mpz_clear(mul_predr); mpz_clear(fz); return success; }
/* binary splitting */ void bs(unsigned long a,unsigned long b,unsigned long level,mpz_t pstack1,mpz_t qstack1,mpz_t gstack1) { unsigned long mid; mpz_t pstack2,qstack2,gstack2; if (b-a==1) { /* g(b-1,b) = (6b-5)(2b-1)(6b-1) p(b-1,b) = b^3 * C^3 / 24 q(b-1,b) = (-1)^b*g(b-1,b)*(A+Bb). */ mpz_set_ui(pstack1,b); mpz_mul_ui(pstack1,pstack1,b); mpz_mul_ui(pstack1,pstack1,b); mpz_mul_ui(pstack1,pstack1,(C/24)*(C/24)); mpz_mul_ui(pstack1,pstack1,C*24); mpz_set_ui(gstack1,2*b-1); mpz_mul_ui(gstack1,gstack1,6*b-1); mpz_mul_ui(gstack1,gstack1,6*b-5); mpz_set_ui(qstack1,b); mpz_mul_ui(qstack1,qstack1,B); mpz_add_ui(qstack1,qstack1,A); mpz_mul (qstack1,qstack1,gstack1); if (b%2) mpz_neg(qstack1,qstack1); } else { mpz_init(pstack2); mpz_init(qstack2); mpz_init(gstack2); if (b-a==2) { mpz_set_ui(pstack1,(b-1)); mpz_mul_ui(pstack1,pstack1,(b-1)); mpz_mul_ui(pstack1,pstack1,(b-1)); mpz_mul_ui(pstack1,pstack1,(C/24)*(C/24)); mpz_mul_ui(pstack1,pstack1,C*24); mpz_set_ui(gstack1,2*(b-1)-1); mpz_mul_ui(gstack1,gstack1,6*(b-1)-1); mpz_mul_ui(gstack1,gstack1,6*(b-1)-5); mpz_set_ui(qstack1,(b-1)); mpz_mul_ui(qstack1,qstack1,B); mpz_add_ui(qstack1,qstack1,A); mpz_mul (qstack1,qstack1,gstack1); if ((b-1)%2) mpz_neg(qstack1,qstack1); mpz_set_ui(pstack2,b); mpz_mul_ui(pstack2,pstack2,b); mpz_mul_ui(pstack2,pstack2,b); mpz_mul_ui(pstack2,pstack2,(C/24)*(C/24)); mpz_mul_ui(pstack2,pstack2,C*24); mpz_set_ui(gstack2,2*b-1); mpz_mul_ui(gstack2,gstack2,6*b-1); mpz_mul_ui(gstack2,gstack2,6*b-5); mpz_set_ui(qstack2,b); mpz_mul_ui(qstack2,qstack2,B); mpz_add_ui(qstack2,qstack2,A); mpz_mul (qstack2,qstack2,gstack2); if (b%2) mpz_neg(qstack2,qstack2); } else { /* p(a,b) = p(a,m) * p(m,b) g(a,b) = g(a,m) * g(m,b) q(a,b) = q(a,m) * p(m,b) + q(m,b) * g(a,m) */ mid = a+(b-a)*0.5224; /* tuning parameter */ #ifdef _OPENMP // #pragma omp task firstprivate(mid,a) shared(pstack1,qstack1,gstack1) if (level < 4) #pragma omp task firstprivate(mid,a) shared(pstack1,qstack1,gstack1) bs(a,mid,level+1,pstack1,qstack1,gstack1); // #pragma omp task firstprivate(mid,b) shared(pstack2,qstack2,gstack2) bs(mid,b,level+1,pstack2,qstack2,gstack2); #pragma omp taskwait #else bs(a,mid,level+1,pstack1,qstack1,gstack1); bs(mid,b,level+1,pstack2,qstack2,gstack2); #endif } mpz_mul(pstack1,pstack1,pstack2); mpz_mul(qstack1,qstack1,pstack2); mpz_addmul(qstack1,qstack2,gstack1); if (b < terms) { mpz_mul(gstack1,gstack1,gstack2); } mpz_clear(pstack2); mpz_clear(qstack2); mpz_clear(gstack2); } }
/* If x^y is exactly representable (with maybe a larger precision than z), round it in z and return the (mpc) inexact flag in [0, 10]. If x^y is not exactly representable, return -1. If intermediate computations lead to numbers of more than maxprec bits, then abort and return -2 (in that case, to avoid loops, mpc_pow_exact should be called again with a larger value of maxprec). Assume one of Re(x) or Im(x) is non-zero, and y is non-zero (y is real). Warning: z and x might be the same variable, same for Re(z) or Im(z) and y. In case -1 or -2 is returned, z is not modified. */ static int mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd, mpfr_prec_t maxprec) { mpfr_exp_t ec, ed, ey; mpz_t my, a, b, c, d, u; unsigned long int t; int ret = -2; int sign_rex = mpfr_signbit (mpc_realref(x)); int sign_imx = mpfr_signbit (mpc_imagref(x)); int x_imag = mpfr_zero_p (mpc_realref(x)); int z_is_y = 0; mpfr_t copy_of_y; if (mpc_realref (z) == y || mpc_imagref (z) == y) { z_is_y = 1; mpfr_init2 (copy_of_y, mpfr_get_prec (y)); mpfr_set (copy_of_y, y, MPFR_RNDN); } mpz_init (my); mpz_init (a); mpz_init (b); mpz_init (c); mpz_init (d); mpz_init (u); ey = mpfr_get_z_exp (my, y); /* normalize so that my is odd */ t = mpz_scan1 (my, 0); ey += (mpfr_exp_t) t; mpz_tdiv_q_2exp (my, my, t); /* y = my*2^ey with my odd */ if (x_imag) { mpz_set_ui (c, 0); ec = 0; } else ec = mpfr_get_z_exp (c, mpc_realref(x)); if (mpfr_zero_p (mpc_imagref(x))) { mpz_set_ui (d, 0); ed = ec; } else { ed = mpfr_get_z_exp (d, mpc_imagref(x)); if (x_imag) ec = ed; } /* x = c*2^ec + I * d*2^ed */ /* equalize the exponents of x */ if (ec < ed) { mpz_mul_2exp (d, d, (unsigned long int) (ed - ec)); if ((mpfr_prec_t) mpz_sizeinbase (d, 2) > maxprec) goto end; } else if (ed < ec) { mpz_mul_2exp (c, c, (unsigned long int) (ec - ed)); if ((mpfr_prec_t) mpz_sizeinbase (c, 2) > maxprec) goto end; ec = ed; } /* now ec=ed and x = (c + I * d) * 2^ec */ /* divide by two if possible */ if (mpz_cmp_ui (c, 0) == 0) { t = mpz_scan1 (d, 0); mpz_tdiv_q_2exp (d, d, t); ec += (mpfr_exp_t) t; } else if (mpz_cmp_ui (d, 0) == 0) { t = mpz_scan1 (c, 0); mpz_tdiv_q_2exp (c, c, t); ec += (mpfr_exp_t) t; } else /* neither c nor d is zero */ { unsigned long v; t = mpz_scan1 (c, 0); v = mpz_scan1 (d, 0); if (v < t) t = v; mpz_tdiv_q_2exp (c, c, t); mpz_tdiv_q_2exp (d, d, t); ec += (mpfr_exp_t) t; } /* now either one of c, d is odd */ while (ey < 0) { /* check if x is a square */ if (ec & 1) { mpz_mul_2exp (c, c, 1); mpz_mul_2exp (d, d, 1); ec --; } /* now ec is even */ if (mpc_perfect_square_p (a, b, c, d) == 0) break; mpz_swap (a, c); mpz_swap (b, d); ec /= 2; ey ++; } if (ey < 0) { ret = -1; /* not representable */ goto end; } /* Now ey >= 0, it thus suffices to check that x^my is representable. If my > 0, this is always true. If my < 0, we first try to invert (c+I*d)*2^ec. */ if (mpz_cmp_ui (my, 0) < 0) { /* If my < 0, 1 / (c + I*d) = (c - I*d)/(c^2 + d^2), thus a sufficient condition is that c^2 + d^2 is a power of two, assuming |c| <> |d|. Assume a prime p <> 2 divides c^2 + d^2, then if p does not divide c or d, 1 / (c + I*d) cannot be exact. If p divides both c and d, then we can write c = p*c', d = p*d', and 1 / (c + I*d) = 1/p * 1/(c' + I*d'). This shows that if 1/(c+I*d) is exact, then 1/(c' + I*d') is exact too, and we are back to the previous case. In conclusion, a necessary and sufficient condition is that c^2 + d^2 is a power of two. */ /* FIXME: we could first compute c^2+d^2 mod a limb for example */ mpz_mul (a, c, c); mpz_addmul (a, d, d); t = mpz_scan1 (a, 0); if (mpz_sizeinbase (a, 2) != 1 + t) /* a is not a power of two */ { ret = -1; /* not representable */ goto end; } /* replace (c,d) by (c/(c^2+d^2), -d/(c^2+d^2)) */ mpz_neg (d, d); ec = -ec - (mpfr_exp_t) t; mpz_neg (my, my); } /* now ey >= 0 and my >= 0, and we want to compute [(c + I * d) * 2^ec] ^ (my * 2^ey). We first compute [(c + I * d) * 2^ec]^my, then square ey times. */ t = mpz_sizeinbase (my, 2) - 1; mpz_set (a, c); mpz_set (b, d); ed = ec; /* invariant: (a + I*b) * 2^ed = ((c + I*d) * 2^ec)^trunc(my/2^t) */ while (t-- > 0) { unsigned long int v, w; /* square a + I*b */ mpz_mul (u, a, b); mpz_mul (a, a, a); mpz_submul (a, b, b); mpz_mul_2exp (b, u, 1); ed *= 2; if (mpz_tstbit (my, t)) /* multiply by c + I*d */ { mpz_mul (u, a, c); mpz_submul (u, b, d); /* ac-bd */ mpz_mul (b, b, c); mpz_addmul (b, a, d); /* bc+ad */ mpz_swap (a, u); ed += ec; } /* remove powers of two in (a,b) */ if (mpz_cmp_ui (a, 0) == 0) { w = mpz_scan1 (b, 0); mpz_tdiv_q_2exp (b, b, w); ed += (mpfr_exp_t) w; } else if (mpz_cmp_ui (b, 0) == 0) { w = mpz_scan1 (a, 0); mpz_tdiv_q_2exp (a, a, w); ed += (mpfr_exp_t) w; } else { w = mpz_scan1 (a, 0); v = mpz_scan1 (b, 0); if (v < w) w = v; mpz_tdiv_q_2exp (a, a, w); mpz_tdiv_q_2exp (b, b, w); ed += (mpfr_exp_t) w; } if ( (mpfr_prec_t) mpz_sizeinbase (a, 2) > maxprec || (mpfr_prec_t) mpz_sizeinbase (b, 2) > maxprec) goto end; } /* now a+I*b = (c+I*d)^my */ while (ey-- > 0) { unsigned long sa, sb; /* square a + I*b */ mpz_mul (u, a, b); mpz_mul (a, a, a); mpz_submul (a, b, b); mpz_mul_2exp (b, u, 1); ed *= 2; /* divide by largest 2^n possible, to avoid many loops for e.g., (2+2*I)^16777216 */ sa = mpz_scan1 (a, 0); sb = mpz_scan1 (b, 0); sa = (sa <= sb) ? sa : sb; mpz_tdiv_q_2exp (a, a, sa); mpz_tdiv_q_2exp (b, b, sa); ed += (mpfr_exp_t) sa; if ( (mpfr_prec_t) mpz_sizeinbase (a, 2) > maxprec || (mpfr_prec_t) mpz_sizeinbase (b, 2) > maxprec) goto end; } ret = mpfr_set_z (mpc_realref(z), a, MPC_RND_RE(rnd)); ret = MPC_INEX(ret, mpfr_set_z (mpc_imagref(z), b, MPC_RND_IM(rnd))); mpfr_mul_2si (mpc_realref(z), mpc_realref(z), ed, MPC_RND_RE(rnd)); mpfr_mul_2si (mpc_imagref(z), mpc_imagref(z), ed, MPC_RND_IM(rnd)); end: mpz_clear (my); mpz_clear (a); mpz_clear (b); mpz_clear (c); mpz_clear (d); mpz_clear (u); if (ret >= 0 && x_imag) fix_sign (z, sign_rex, sign_imx, (z_is_y) ? copy_of_y : y); if (z_is_y) mpfr_clear (copy_of_y); return ret; }