unsigned long fmpz_multi_mod_ui_basecase(unsigned long * out, fmpz_t in, unsigned long * primes, unsigned long num_primes) { for (unsigned long i = 0; i < num_primes; i++) { out[i] = fmpz_mod_ui(in, primes[i]); } }
void poly_starmultiply(fmpz_poly_t c, const fmpz_poly_t a, const fmpz_poly_t b, const ntru_params *params, uint32_t modulus) { fmpz_poly_t a_tmp; fmpz_t c_coeff_k; fmpz_poly_init(a_tmp); fmpz_init(c_coeff_k); /* avoid side effects */ fmpz_poly_set(a_tmp, a); fmpz_poly_zero(c); for (int k = params->N - 1; k >= 0; k--) { int j; j = k + 1; fmpz_set_si(c_coeff_k, 0); for (int i = params->N - 1; i >= 0; i--) { fmpz *a_tmp_coeff_i, *b_coeff_j; if (j == (int)(params->N)) j = 0; a_tmp_coeff_i = fmpz_poly_get_coeff_ptr(a_tmp, i); b_coeff_j = fmpz_poly_get_coeff_ptr(b, j); if (fmpz_cmp_si_n(a_tmp_coeff_i, 0) && fmpz_cmp_si_n(b_coeff_j, 0)) { fmpz_t fmpz_tmp; fmpz_init(fmpz_tmp); fmpz_mul(fmpz_tmp, a_tmp_coeff_i, b_coeff_j); fmpz_add(fmpz_tmp, fmpz_tmp, c_coeff_k); fmpz_mod_ui(c_coeff_k, fmpz_tmp, modulus); fmpz_poly_set_coeff_fmpz(c, k, c_coeff_k); fmpz_clear(fmpz_tmp); } j++; } fmpz_clear(c_coeff_k); } fmpz_poly_clear(a_tmp); }
int main(void) { int i, result; flint_rand_t state; printf("evaluate_mod...."); fflush(stdout); flint_randinit(state); /* Compare with evaluation over the integers */ for (i = 0; i < 10000; i++) { fmpz_t b, s; fmpz_poly_t f; mp_limb_t a, n, r; fmpz_poly_init(f); fmpz_poly_randtest(f, state, n_randint(state, 10), 20); n = n_randtest_not_zero(state); a = n_randint(state, n); fmpz_init(b); fmpz_init(s); fmpz_set_ui(b, a); r = fmpz_poly_evaluate_mod(f, a, n); fmpz_poly_evaluate_fmpz(s, f, b); result = (r == fmpz_mod_ui(s, s, n)); if (!result) { printf("FAIL:\n"); fmpz_poly_print(f), printf("\n\n"); gmp_printf("a = %Mu\n\n", a); gmp_printf("n = %Mu\n\n", n); gmp_printf("r = %Mu\n\n", r); printf("s = "), fmpz_print(s), printf("\n\n"); abort(); } fmpz_poly_clear(f); fmpz_clear(b); fmpz_clear(s); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void fmpz_multi_CRT_ui(fmpz_t output, unsigned long * residues, fmpz_comb_t comb, fmpz_t ** comb_temp) { ulong i, j, k; ulong n = comb->n; ulong num; ulong log_res; mp_limb_t * ptr; ulong size; ulong num_primes = comb->num_primes; if (num_primes == 1) // the output is less than a single prime, so just output the result { unsigned long p = comb->primes[0]; if ((p - residues[0]) < residues[0]) fmpz_set_si(output, (long) (residues[0] - p)); else fmpz_set_ui(output, residues[0]); return; } // first layer of reconstruction num = (1L<<n); mp_limb_t temps[3]; mp_limb_t temp2s[3]; for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) { fmpz_set_ui(temps, residues[i]); fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1])); fmpz_sub_ui_inplace(temp2s, residues[i + 1]); temp2s[0] = -temp2s[0]; fmpz_mul(temps, temp2s, comb->res[0][j]); fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1])); fmpz_mul_ui(temps, temp2s, comb->primes[i]); fmpz_add_ui(comb_temp[0][j], temps, residues[i]); } if (i < num_primes) fmpz_set_ui(comb_temp[0][j], residues[i]); // compute other layers of reconstruction fmpz_t temp = (fmpz_t) flint_heap_alloc(2*num + 1); fmpz_t temp2 = (fmpz_t) flint_heap_alloc(2*num + 1); num /= 2; log_res = 1; while (log_res < n) { for (i = 0, j = 0; i < num; i += 2, j++) { if (fmpz_is_one(comb->comb[log_res-1][i+1])) { if (!fmpz_is_one(comb->comb[log_res-1][i])) fmpz_set(comb_temp[log_res][j], comb_temp[log_res-1][i]); } else { fmpz_mod(temp2, comb_temp[log_res-1][i], comb->comb[log_res-1][i+1]); fmpz_sub(temp, temp2, comb_temp[log_res-1][i+1]); temp[0] = -temp[0]; fmpz_mul(temp2, temp, comb->res[log_res][j]); fmpz_mod(temp, temp2, comb->comb[log_res-1][i+1]); fmpz_mul(temp2, temp, comb->comb[log_res-1][i]); fmpz_add(comb_temp[log_res][j], temp2, comb_temp[log_res-1][i]); } } log_res++; num /= 2; } // write out the output __fmpz_multi_CRT_sign(comb_temp[log_res - 1][0], comb_temp[log_res - 1][0], comb); fmpz_set(output, comb_temp[log_res - 1][0]); flint_heap_free(temp2); //temp2 flint_heap_free(temp); //temp }
void _qseive(const mp_limb_t n, const mp_limb_t B) { nmod_sparse_mat_t M; mp_limb_t quad, *quads, *xs, x, i = 0, j, piB = n_prime_pi(B); const mp_limb_t * ps = n_primes_arr_readonly(piB + 2); const double * pinvs = n_prime_inverses_arr_readonly(piB + 2); mzd_t *K; /* init */ quads = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *)); xs = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *)); K = mzd_init(piB + 1, 1); nmod_sparse_mat_init(M, piB + 1, piB + 1, 2); printf("init done\n"); printf("using %ld primes\n", piB); /* seive */ for (x = n_sqrt(n), i = 0; i <= piB; x++) { quad = x*x - n; if (quad == 0) continue; for (j = 0; j < piB; j++) n_remove2_precomp(&quad, ps[j], pinvs[j]); if (quad == 1) /* was B-smooth */ { quads[i] = x*x - n; quad = x*x - n; for (j = 0; j < piB; j++) { if (n_remove2_precomp(&quad, ps[j], pinvs[j]) % 2) _nmod_sparse_mat_set_entry(M, j, i, M->row_supports[j], 1); } xs[i] = x; i++; } } printf("data collection done\n"); n_cleanup_primes(); _bw(K, M, 1, 2, 7, 7); printf("procesing complete\n"); mzd_print(K); int done = 0; for (j = 0; !done; j++) { fmpz_t a, b, diff, N; fmpz_init_set_ui(a, 1); fmpz_init_set_ui(b, 1); fmpz_init_set_ui(N, n); fmpz_init(diff); for (i = 0; i < piB; i++) { if (mzd_read_bit(K, i, j)) { fmpz_mul_ui(a, a, xs[i]); fmpz_mul_ui(b, b, quads[i]); } } assert(fmpz_is_square(b)); fmpz_sqrt(b, b); if (fmpz_mod_ui(a, a, n) != fmpz_mod_ui(b, b, n) && fmpz_mod_ui(a, a, n) != n - fmpz_mod_ui(b, b, n)) { done = 1; fmpz_print(a); printf("\n"); fmpz_print(b); printf("\n"); fmpz_sub(diff, a, b); fmpz_gcd(a, diff, N); fmpz_divexact(b, N, a); fmpz_print(a); printf("\n"); fmpz_print(b); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(N); fmpz_clear(diff); } /* cleanup */ free(quads); free(xs); mzd_free(K); nmod_sparse_mat_clear(M); return; }
bool poly_inverse_poly_p(fmpz_poly_t Fp, const fmpz_poly_t a, const ntru_params *params) { bool retval = false; int k = 0, j = 0; fmpz *b_last; fmpz_poly_t a_tmp, b, c, f, g; /* general initialization of temp variables */ fmpz_poly_init(b); fmpz_poly_set_coeff_ui(b, 0, 1); fmpz_poly_init(c); fmpz_poly_init(f); fmpz_poly_set(f, a); /* set g(x) = x^N − 1 */ fmpz_poly_init(g); fmpz_poly_set_coeff_si(g, 0, -1); fmpz_poly_set_coeff_si(g, params->N, 1); /* avoid side effects */ fmpz_poly_init(a_tmp); fmpz_poly_set(a_tmp, a); fmpz_poly_zero(Fp); while (1) { while (fmpz_poly_get_coeff_ptr(f, 0) && fmpz_is_zero(fmpz_poly_get_coeff_ptr(f, 0))) { for (uint32_t i = 1; i <= params->N; i++) { fmpz *f_coeff = fmpz_poly_get_coeff_ptr(f, i); fmpz *c_coeff = fmpz_poly_get_coeff_ptr(c, params->N - i); /* f(x) = f(x) / x */ fmpz_poly_set_coeff_fmpz_n(f, i - 1, f_coeff); /* c(x) = c(x) * x */ fmpz_poly_set_coeff_fmpz_n(c, params->N + 1 - i, c_coeff); } fmpz_poly_set_coeff_si(f, params->N, 0); fmpz_poly_set_coeff_si(c, 0, 0); k++; if (fmpz_poly_degree(f) == -1) goto cleanup; } if (fmpz_poly_is_zero(g) == 1) goto cleanup; if (fmpz_poly_degree(f) == 0) break; if (fmpz_poly_degree(f) < fmpz_poly_degree(g)) { /* exchange f and g and exchange b and c */ fmpz_poly_swap(f, g); fmpz_poly_swap(b, c); } { fmpz_poly_t c_tmp, g_tmp; fmpz_t u, mp_tmp; fmpz_init(u); fmpz_zero(u); fmpz_init_set(mp_tmp, fmpz_poly_get_coeff_ptr(f, 0)); fmpz_poly_init(g_tmp); fmpz_poly_set(g_tmp, g); fmpz_poly_init(c_tmp); fmpz_poly_set(c_tmp, c); /* u = f[0] * g[0]^(-1) mod p */ /* = (f[0] mod p) * (g[0] inverse mod p) mod p */ fmpz_invmod_ui(u, fmpz_poly_get_coeff_ptr(g, 0), params->p); fmpz_mod_ui(mp_tmp, mp_tmp, params->p); fmpz_mul(u, mp_tmp, u); fmpz_mod_ui(u, u, params->p); /* f = f - u * g mod p */ fmpz_poly_scalar_mul_fmpz(g_tmp, g_tmp, u); fmpz_poly_sub(f, f, g_tmp); fmpz_poly_mod_unsigned(f, params->p); /* b = b - u * c mod p */ fmpz_poly_scalar_mul_fmpz(c_tmp, c_tmp, u); fmpz_poly_sub(b, b, c_tmp); fmpz_poly_mod_unsigned(b, params->p); fmpz_clear(u); fmpz_poly_clear(g_tmp); fmpz_poly_clear(c_tmp); } } k = k % params->N; b_last = fmpz_poly_get_coeff_ptr(b, params->N); if (fmpz_cmp_si_n(b_last, 0)) goto cleanup; /* Fp(x) = x^(N-k) * b(x) */ for (int i = params->N - 1; i >= 0; i--) { fmpz *b_i; /* b(X) = f[0]^(-1) * b(X) (mod p) */ { fmpz_t mp_tmp; fmpz_init(mp_tmp); fmpz_invmod_ui(mp_tmp, fmpz_poly_get_coeff_ptr(f, 0), params->p); if (fmpz_poly_get_coeff_ptr(b, i)) { fmpz_mul(fmpz_poly_get_coeff_ptr(b, i), fmpz_poly_get_coeff_ptr(b, i), mp_tmp); fmpz_mod_ui(fmpz_poly_get_coeff_ptr(b, i), fmpz_poly_get_coeff_ptr(b, i), params->p); } } j = i - k; if (j < 0) j = j + params->N; b_i = fmpz_poly_get_coeff_ptr(b, i); fmpz_poly_set_coeff_fmpz_n(Fp, j, b_i); } /* check if the f * Fp = 1 (mod p) condition holds true */ fmpz_poly_set(a_tmp, a); poly_starmultiply(a_tmp, a_tmp, Fp, params, params->p); if (fmpz_poly_is_one(a_tmp)) retval = true; else fmpz_poly_zero(Fp); cleanup: fmpz_poly_clear(a_tmp); fmpz_poly_clear(b); fmpz_poly_clear(c); fmpz_poly_clear(f); fmpz_poly_clear(g); return retval; }
int main(void) { int i, j, result = 1; fmpz_t t; flint_rand_t state; flint_randinit(state); printf("derivative...."); fflush(stdout); fmpz_init(t); /* Check derivative by hand */ for (i = 0; i < 10000; i++) { nmod_poly_t a, b; mp_limb_t n = n_randtest_not_zero(state); nmod_poly_init(a, n); nmod_poly_init(b, n); nmod_poly_randtest(a, state, n_randint(state, 100)); nmod_poly_derivative(b, a); if (a->length <= 1) result = (b->length == 0); else { for (j = 1; j < a->length; j++) { fmpz_set_ui(t, nmod_poly_get_coeff_ui(a, j)); fmpz_mul_ui(t, t, j); fmpz_mod_ui(t, t, n); result &= (fmpz_get_ui(t) == nmod_poly_get_coeff_ui(b, j - 1)); } } if (!result) { printf("FAIL:\n"); printf("a->length = %ld, n = %lu\n", a->length, a->mod.n); nmod_poly_print(a), printf("\n\n"); nmod_poly_print(b), printf("\n\n"); abort(); } nmod_poly_clear(a); nmod_poly_clear(b); } fmpz_clear(t); /* Check aliasing */ for (i = 0; i < 10000; i++) { nmod_poly_t a, b; mp_limb_t n = n_randtest_not_zero(state); nmod_poly_init(a, n); nmod_poly_init(b, n); nmod_poly_randtest(a, state, n_randint(state, 100)); nmod_poly_derivative(b, a); nmod_poly_derivative(a, a); result = nmod_poly_equal(a, b); if (!result) { printf("FAIL:\n"); printf("a->length = %ld, n = %lu\n", a->length, a->mod.n); nmod_poly_print(a), printf("\n\n"); nmod_poly_print(b), printf("\n\n"); abort(); } nmod_poly_clear(a); nmod_poly_clear(b); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }