mp_limb_t n_primitive_root_prime_prefactor(mp_limb_t p, n_factor_t * factors) { slong i; int found; mp_limb_t result, a, pm1; double pinv; if (p == 2) { return 1; } pm1 = p - 1; pinv = n_precompute_inverse(p); for (a = 2; a < p; a++) { found = 1; for (i = 0; i < factors->num; i++) { result = n_powmod_precomp(a, pm1 / factors->p[i], p, pinv); if (result == 1) { found = 0; break; } } if (found) { return a; } } flint_printf("Exception (n_primitive_root_prime_prefactor). root not found.\n"); abort(); }
int main(void) { int i, result; flint_rand_t state; printf("powmod_precomp...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 100000; i++) { mp_limb_t a, d, r1, r2, bits; mpz_t a_m, d_m, r2_m; mp_limb_signed_t exp; double dpre; mpz_init(a_m); mpz_init(d_m); mpz_init(r2_m); bits = n_randint(state, FLINT_D_BITS) + 1; d = n_randbits(state, bits); do { a = n_randint(state, d); } while (n_gcd(d, a) != 1UL); exp = n_randtest(state); dpre = n_precompute_inverse(d); r1 = n_powmod_precomp(a, exp, d, dpre); mpz_set_ui(a_m, a); mpz_set_ui(d_m, d); if (exp < 0L) { mpz_powm_ui(r2_m, a_m, -exp, d_m); mpz_invert(r2_m, r2_m, d_m); } else mpz_powm_ui(r2_m, a_m, exp, d_m); r2 = mpz_get_ui(r2_m); result = (r1 == r2); if (!result) { printf("FAIL:\n"); printf("a = %lu, exp = %ld, d = %lu\n", a, exp, d); printf("r1 = %lu, r2 = %lu\n", r1, r2); abort(); } mpz_clear(a_m); mpz_clear(d_m); mpz_clear(r2_m); } flint_randclear(state); printf("PASS\n"); return 0; }