void zn_array_invert (ulong* res, const ulong* op, size_t n, const zn_mod_t mod) { ZNP_ASSERT (n >= 1); // for now assume input is monic ZNP_ASSERT (op[0] == 1); if (n == 1) { res[0] = 1; return; } size_t half = (n + 1) / 2; // ceil(n / 2) // recursively obtain the first half of the output zn_array_invert (res, op, half, mod); // extend to second half of the output if (mod->m & 1) zn_array_invert_extend_fft (res + half, res, op, half, n - half, mod); else zn_array_invert_extend (res + half, res, op, half, n - half, mod); }
/* Tests zn_array_invert() for a given series length and modulus. */ int testcase_zn_array_invert (size_t n, const zn_mod_t mod) { ulong* op = (ulong*) malloc (sizeof (ulong) * n); ulong* res = (ulong*) malloc (sizeof (ulong) * n); ulong* check = (ulong*) malloc (sizeof (ulong) * (2 * n - 1)); // make up random input poly size_t i; op[0] = 1; for (i = 1; i < n; i++) op[i] = random_ulong (mod->m); // compute inverse zn_array_invert (res, op, n, mod); // multiply by original series and check we get 1 ref_zn_array_mul (check, op, n, res, n, mod); int success = (check[0] == 1); for (i = 1; i < n; i++) success = success && (check[i] == 0); free (check); free (res); free (op); return success; }