1 /*
2    mulmid_ks-test.c:  test code for functions in mulmid_ks.c
3 
4    Copyright (C) 2007, 2008, David Harvey
5 
6    This file is part of the zn_poly library (version 0.9).
7 
8    This program is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 2 of the License, or
11    (at your option) version 3 of the License.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #include "support.h"
24 #include "zn_poly_internal.h"
25 
26 
27 /*
28    Tests zn_array_mulmid_KSk, for given lengths, reduction algorithm, modulus.
29    1 <= k <= 4 indicates which KS variant to call.
30    Returns 1 on success.
31 */
32 int
testcase_zn_array_mulmid_KS(int k,size_t n1,size_t n2,int redc,const zn_mod_t mod)33 testcase_zn_array_mulmid_KS (int k, size_t n1, size_t n2,
34                              int redc, const zn_mod_t mod)
35 {
36    // disallow REDC if modulus is even
37    if (!(mod->m & 1))
38       redc = 0;
39 
40    ulong* buf1 = (ulong*) malloc (sizeof (ulong) * n1);
41    ulong* buf2 = (ulong*) malloc (sizeof (ulong) * n2);
42    ulong* ref = (ulong*) malloc (sizeof (ulong) * (n1 - n2 + 1));
43    ulong* res = (ulong*) malloc (sizeof (ulong) * (n1 - n2 + 1));
44 
45    // generate random polys
46    size_t i;
47    for (i = 0; i < n1; i++)
48       buf1[i] = random_ulong (mod->m);
49    for (i = 0; i < n2; i++)
50       buf2[i] = random_ulong (mod->m);
51 
52    // compare target implementation against reference implementation
53    ref_zn_array_mulmid (ref, buf1, n1, buf2, n2, mod);
54 
55    switch (k)
56    {
57       case 1:  zn_array_mulmid_KS1 (res, buf1, n1, buf2, n2, redc, mod); break;
58       case 2:  zn_array_mulmid_KS2 (res, buf1, n1, buf2, n2, redc, mod); break;
59       case 3:  zn_array_mulmid_KS3 (res, buf1, n1, buf2, n2, redc, mod); break;
60       case 4:  zn_array_mulmid_KS4 (res, buf1, n1, buf2, n2, redc, mod); break;
61       default:
62          printf ("oops!\n"); abort ();
63    }
64 
65    if (redc)
66       // correct for REDC reduction
67       ref_zn_array_scalar_mul (res, res, n1 - n2 + 1, mod->m - mod->B, mod);
68 
69    int success = !zn_array_cmp (ref, res, n1 - n2 + 1);
70 
71    free (res);
72    free (ref);
73    free (buf2);
74    free (buf1);
75 
76    return success;
77 }
78 
79 
80 /*
81    tests zn_array_mulmid_KSk() on a range of input cases,
82    where 1 <= k <= 4
83 */
84 int
test_zn_array_mulmid_KSk(unsigned k,int quick)85 test_zn_array_mulmid_KSk (unsigned k, int quick)
86 {
87    int success = 1;
88    int b, trial, redc;
89    size_t n1, n2;
90    zn_mod_t mod;
91 
92    // first try a dense range of "small" problems
93 
94    for (b = 2; b <= ULONG_BITS && success; b++)
95    for (n2 = 1; n2 <= 30 && success; n2 += (quick ? 5 : 1))
96    for (n1 = n2; n1 <= 30 && success; n1 += (quick ? 5 : 1))
97    for (redc = 0; redc < 2 && success; redc++)
98    for (trial = 0; trial < (quick ? 1 : 10) && success; trial++)
99    {
100       zn_mod_init (mod, random_modulus (b, 0));
101       success = success && testcase_zn_array_mulmid_KS (k, n1, n2, redc, mod);
102       zn_mod_clear(mod);
103    }
104 
105    // now try some random larger problems
106 
107    for (b = 2; b <= ULONG_BITS && success; b++)
108    for (redc = 0; redc < 2 && success; redc++)
109    for (trial = 0; trial < (quick ? 3 : 200) && success; trial++)
110    {
111       size_t t1 = random_ulong (quick ? 250 : 1000) + 1;
112       size_t t2 = random_ulong (quick ? 250 : 1000) + 1;
113       n1 = ZNP_MAX (t1, t2);
114       n2 = ZNP_MIN (t1, t2);
115 
116       zn_mod_init (mod, random_modulus (b, 0));
117       success = success && testcase_zn_array_mulmid_KS (k, n1, n2, redc, mod);
118       zn_mod_clear(mod);
119    }
120 
121    return success;
122 }
123 
124 
test_zn_array_mulmid_KS1(int quick)125 int test_zn_array_mulmid_KS1 (int quick)
126 {
127    return test_zn_array_mulmid_KSk (1, quick);
128 }
129 
test_zn_array_mulmid_KS2(int quick)130 int test_zn_array_mulmid_KS2 (int quick)
131 {
132    return test_zn_array_mulmid_KSk (2, quick);
133 }
134 
test_zn_array_mulmid_KS3(int quick)135 int test_zn_array_mulmid_KS3 (int quick)
136 {
137    return test_zn_array_mulmid_KSk (3, quick);
138 }
139 
test_zn_array_mulmid_KS4(int quick)140 int test_zn_array_mulmid_KS4 (int quick)
141 {
142    return test_zn_array_mulmid_KSk (4, quick);
143 }
144 
145 
146 // end of file ****************************************************************
147