/* Tests zn_array_mul_fft_dft, for given lengths, lgT, modulus. Returns 1 on success. */ int testcase_zn_array_mul_fft_dft (size_t n1, size_t n2, unsigned lgT, const zn_mod_t mod) { ulong* buf1 = (ulong*) malloc (sizeof (ulong) * n1); ulong* buf2 = (ulong*) malloc (sizeof (ulong) * n2); ulong* ref = (ulong*) malloc (sizeof (ulong) * (n1 + n2 - 1)); ulong* res = (ulong*) malloc (sizeof (ulong) * (n1 + n2 - 1)); // generate random polys size_t i; for (i = 0; i < n1; i++) buf1[i] = random_ulong (mod->m); for (i = 0; i < n2; i++) buf2[i] = random_ulong (mod->m); // compare target implementation against reference implementation ref_zn_array_mul (ref, buf1, n1, buf2, n2, mod); zn_array_mul_fft_dft (res, buf1, n1, buf2, n2, lgT, mod); int success = !zn_array_cmp (ref, res, n1 + n2 - 1); free (res); free (ref); free (buf2); free (buf1); return success; }
/* 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; }
/* Tests zn_array_mul_fft, for given lengths and modulus. If use_scale is set, zn_array_mul_fft() gets called with a random x (post-scaling factor), otherwise gets called with x == 1. If sqr == 1, tests squaring (n2 is ignored), otherwise ordinary multiplication. Returns 1 on success. */ int testcase_zn_array_mul_fft (size_t n1, size_t n2, int sqr, int use_scale, const zn_mod_t mod) { if (sqr) n2 = n1; ulong* buf1 = (ulong*) malloc (sizeof (ulong) * n1); ulong* buf2 = sqr ? buf1 : (ulong*) malloc (sizeof (ulong) * n2); ulong* ref = (ulong*) malloc (sizeof (ulong) * (n1 + n2 - 1)); ulong* res = (ulong*) malloc (sizeof (ulong) * (n1 + n2 - 1)); // generate random polys size_t i; for (i = 0; i < n1; i++) buf1[i] = random_ulong (mod->m); if (!sqr) for (i = 0; i < n2; i++) buf2[i] = random_ulong (mod->m); ulong x = use_scale ? random_ulong (mod->m) : 1; // compare target implementation against reference implementation ref_zn_array_mul (ref, buf1, n1, buf2, n2, mod); ref_zn_array_scalar_mul (ref, ref, n1 + n2 - 1, x, mod); zn_array_mul_fft (res, buf1, n1, buf2, n2, x, mod); ulong y = zn_array_mul_fft_fudge (n1, n2, sqr, mod); ref_zn_array_scalar_mul (res, res, n1 + n2 - 1, y, mod); int success = !zn_array_cmp (ref, res, n1 + n2 - 1); free (res); free (ref); if (!sqr) free (buf2); free (buf1); return success; }