/* Tests zn_array_mulmid_fft, for given n1, n2, modulus. If use_scale is set, zn_array_mulmid_fft() gets called with a random x (post-scaling factor), otherwise gets called with x == 1. Returns 1 on success. */ int testcase_zn_array_mulmid_fft (size_t n1, size_t n2, int use_scale, 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); ulong x = use_scale ? random_ulong (mod->m) : 1; // compare target implementation against reference implementation ref_zn_array_mulmid (ref, buf1, n1, buf2, n2, mod); ref_zn_array_scalar_mul (ref, ref, n1 - n2 + 1, x, mod); zn_array_mulmid_fft (res, buf1, n1, buf2, n2, x, mod); ulong y = zn_array_mulmid_fft_fudge (n1, n2, 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); free (buf2); free (buf1); return success; }
/* 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; }
int testcase_mpn_smp (size_t n1, size_t n2) { size_t n3 = n1 - n2 + 3; mp_limb_t* buf1 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n1); mp_limb_t* buf2 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n2); mp_limb_t* ref = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n3); mp_limb_t* res = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n3); // generate random inputs ZNP_mpn_random2 (buf1, n1); ZNP_mpn_random2 (buf2, n2); // temporarily lower the karatsuba threshold for more stringent testing unsigned long temp_thresh = ZNP_mpn_smp_kara_thresh; ZNP_mpn_smp_kara_thresh = 5; // compare target against reference implementation ZNP_mpn_smp (res, buf1, n1, buf2, n2); ref_mpn_smp (ref, buf1, n1, buf2, n2); int success = !zn_array_cmp (ref, res, n3); ZNP_mpn_smp_kara_thresh = temp_thresh; free (res); free (ref); free (buf2); free (buf1); return success; }
/* tests zn_array_unpack() once for given n, b, k */ int testcase_zn_array_unpack (size_t n, unsigned b, unsigned k) { size_t buf_size = CEIL_DIV (n * b + k, GMP_NUMB_BITS); size_t size = n * CEIL_DIV (b, ULONG_BITS); mp_limb_t* buf = (mp_limb_t*) malloc (sizeof (mp_limb_t) * buf_size); ulong* res = (ulong*) malloc (sizeof (ulong) * (size + 2)); ulong* ref = (ulong*) malloc (sizeof (ulong) * (size + 2)); // sentries to check buffer overflow res[0] = res[size + 1] = ref[0] = ref[size + 1] = 0x1234; // generate random data mpz_t x; mpz_init (x); mpz_urandomb (x, randstate, n * b); mpz_mul_2exp (x, x, k); mpz_to_mpn (buf, buf_size, x); mpz_clear (x); // run target and reference implementation zn_array_unpack (res + 1, buf, n, b, k); ref_zn_array_unpack (ref + 1, buf, n, b, k); int success = 1; // check sentries success = success && (res[0] == 0x1234); success = success && (ref[0] == 0x1234); success = success && (res[size + 1] == 0x1234); success = success && (ref[size + 1] == 0x1234); // check correct result success = success && (zn_array_cmp (res + 1, ref + 1, size) == 0); free (ref); free (res); free (buf); return success; }
/* Tests mpn_smp_kara for given n. */ int testcase_mpn_smp_kara (size_t n) { mp_limb_t* buf1 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * (2 * n - 1)); mp_limb_t* buf2 = (mp_limb_t*) malloc (sizeof (mp_limb_t) * n); mp_limb_t* ref = (mp_limb_t*) malloc (sizeof (mp_limb_t) * (n + 2)); mp_limb_t* res = (mp_limb_t*) malloc (sizeof (mp_limb_t) * (n + 2)); // generate random inputs ZNP_mpn_random2 (buf1, 2 * n - 1); ZNP_mpn_random2 (buf2, n); // compare target against reference implementation ZNP_mpn_smp_kara (res, buf1, buf2, n); ref_mpn_smp (ref, buf1, 2 * n - 1, buf2, n); int success = !zn_array_cmp (ref, res, n + 2); free (res); free (ref); free (buf2); free (buf1); return success; }