1 #include <stdio.h>
2 #include "bn.h"
3
4
5 /* For table-defined list of tests */
6 struct test
7 {
8 char op; /* operator: plus, minus, multiply, divide */
9 uint64_t a,b,c; /* operands a, b and c - c contains expected result such that [c] = [a] [op] [b] */
10 };
11
12 /* Golden tests - input and expected outputs: */
13 static struct test oracle[] =
14 {
15 {'+', 80, 20, 100 },
16 {'+', 18, 22, 40 },
17 {'+', 12, 8, 20 },
18 {'+', 100080, 20, 100100 },
19 {'+', 18, 559022, 559040 },
20 {'+', 2000000000, 2000000000, 4000000000 },
21 {'+', 0x00FFFF, 1, 0x010000 },
22 {'+', 0x00FFFF00, 0x00000100, 0x01000000 },
23 {'-', 1000001, 1000000, 1 },
24 {'-', 42, 0, 42 },
25 {'-', 101, 100, 1 },
26 {'-', 242, 42, 200 },
27 {'-', 1042, 0, 1042 },
28 {'-', 101010101, 101010100, 1 },
29 {'-', 0x010000, 1, 0x00FFFF },
30 //./build/test_random 1 0000000000f505c2 00000000000fffe0 0000000000e505e2
31 {'-', 0xf505c2, 0x0fffe0, 0xe505e2 },
32 //./build/test_random 1 00000000009f735a 000000000065ffb5 00000000003973a5
33 {'-', 0x9f735a, 0x65ffb5, 0x3973a5 },
34 //./build/test_random 1 0000000000cf7810 000000000004ff34 0000000000ca78dc
35 {'-', 0xcf7810, 0x04ff34, 0xca78dc },
36 //./build/test_random 1 0000000000bbc55f 00000000004eff76 00000000006cc5e9
37 {'-', 0xbbc55f, 0x4eff76, 0x6cc5e9 },
38 {'-', 0x100000, 1, 0x0fffff },
39 {'-', 0x010000, 1, 0x00ffff },
40 //./build/test_random 1 0000000000b5beb4 000000000001ffc4 0000000000b3bef0
41 {'-', 0xb5beb4, 0x01ffc4, 0xb3bef0 },
42 //./build/test_random 1 0000000000707655 000000000050ffa8 00000000001f76ad
43 {'-', 0x707655, 0x50ffa8, 0x1f76ad },
44 //./build/test_random 1 0000000000f0a990 00000000001cffd1 0000000000d3a9bf
45 {'-', 0xf0a990, 0x1cffd1, 0xd3a9bf },
46 {'*', 0x010203, 0x1020, 0x10407060 },
47 {'*', 42, 0, 0 },
48 {'*', 42, 1, 42 },
49 {'*', 42, 2, 84 },
50 {'*', 42, 10, 420 },
51 {'*', 42, 100, 4200 },
52 {'*', 420, 1000, 420000 },
53 {'*', 200, 8, 1600 },
54 {'*', 2, 256, 512 },
55 {'*', 500, 2, 1000 },
56 {'*', 500000, 2, 1000000 },
57 {'*', 500, 500, 250000 },
58 {'*', 1000000000, 2, 2000000000 },
59 {'*', 2, 1000000000, 2000000000 },
60 {'*', 1000000000, 4, 4000000000 },
61 {'/', 0xFFFFFFFF, 0xFFFFFFFF, 1 },
62 {'/', 0xFFFFFFFF, 0x10000, 0xFFFF },
63 {'/', 0xFFFFFFFF, 0x1000, 0xFFFFF },
64 {'/', 0xFFFFFFFF, 0x100, 0xFFFFFF },
65 {'/', 1000000, 1000, 1000 },
66 {'/', 1000000, 10000, 100 },
67 {'/', 1000000, 100000, 10 },
68 {'/', 1000000, 1000000, 1 },
69 {'/', 1000000, 10000000, 0 },
70 {'/', 28, 7, 4 },
71 {'/', 27, 7, 3 },
72 {'/', 26, 7, 3 },
73 {'/', 25, 7, 3 },
74 {'/', 24, 7, 3 },
75 {'/', 23, 7, 3 },
76 {'/', 22, 7, 3 },
77 {'/', 21, 7, 3 },
78 {'/', 20, 7, 2 },
79 {'/', 0, 12, 0 },
80 {'/', 10, 1, 10 },
81 {'/', 0xFFFFFFFF, 1, 0xFFFFFFFF },
82 {'/', 0xFFFFFFFF, 0x10000, 0xFFFF },
83 //./build/test_random 3 0000000000b36627 00000000000dff95 000000000000000c
84 {'/', 0xb36627, 0x0dff95, 0x0c },
85 //./build/test_random 3 0000000000e5a18e 000000000009ff82 0000000000000016
86 {'/', 0xe5a18e, 0x09ff82, 0x16 },
87 //./build/test_random 3 000000000045edd0 000000000004ff1a 000000000000000d
88 {'/', 0x45edd0, 0x04ff1a, 0x0d },
89 {'%', 8, 3, 2 },
90 {'%', 1024, 1000, 24 },
91 {'%', 0xFFFFFF, 1234, 985 },
92 {'%', 0xFFFFFFFF, 0xEF, 0x6D },
93 {'%', 12345678, 16384, 8526 },
94 //mikl@21972:~/c_bignum2$ ./build/test_random 8 0000000000e7a344 000000000071ffe8 000000000003a374
95 {'%', 0xe7a344, 0x71ffe8, 0x03a374 },
96 //./build/test_random 8 0000000000a3a9a1 000000000002ff44 000000000001d149
97 {'%', 0xa3a9a1, 0x2ff44, 0x1d149 },
98 //./build/test_random 8 0000000000c128b2 000000000060ff61 0000000000602951
99 {'%', 0xc128b2, 0x60ff61, 0x602951 },
100 //./build/test_random 8 0000000000dc2254 0000000000517fea 0000000000392280
101 {'%', 0xDC2254, 0x517FEA, 0x392280 },
102 //./build/test_random 8 0000000000769c99 00000000002cffda 00000000001c9ce5
103 {'%', 0x769c99, 0x2cffda, 0x1c9ce5 },
104 //./build/test_random 8 0000000000c19076 000000000031ffd4 00000000002b90fa
105 {'%', 0xc19076, 0x31ffd4, 0x2b90fa },
106 {'&', 0xFFFFFFFF, 0x005500AA, 0x005500AA },
107 {'&', 7, 3, 3 },
108 {'&', 0xFFFFFFFF, 0, 0 },
109 {'&', 0, 0xFFFFFFFF, 0 },
110 {'&', 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
111 {'|', 0xFFFFFFFF, 0, 0xFFFFFFFF },
112 {'|', 0, 0xFFFFFFFF, 0xFFFFFFFF },
113 {'|', 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF },
114 {'|', 0x55555555, 0xAAAAAAAA, 0xFFFFFFFF },
115 {'|', 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
116 {'|', 4, 3, 7 },
117 {'^', 7, 4, 3 },
118 {'^', 0xFFFF, 0x5555, 0xAAAA },
119 {'^', 0x5555, 0xAAAA, 0xFFFF },
120 {'^', 0xAAAA, 0x5555, 0xFFFF },
121 {'^', 0x0000, 0xFFFF, 0xFFFF },
122 {'^', 0x5555, 0xFFFF, 0xAAAA },
123 {'^', 0xAAAA, 0xFFFF, 0x5555 },
124 {'p', 2, 0, 1 },
125 {'p', 2, 1, 2 },
126 {'p', 2, 2, 4 },
127 {'p', 2, 3, 8 },
128 {'p', 2, 10, 1024 },
129 {'p', 2, 20, 1048576 },
130 {'p', 2, 30, 1073741824 },
131 {'<', 1, 0, 1},
132 {'<', 1, 1, 2},
133 {'<', 1, 2, 4},
134 {'<', 1, 3, 8},
135 {'<', 1, 4, 16},
136 {'<', 1, 5, 32},
137 {'<', 1, 6, 64},
138 {'<', 1, 7, 128},
139 {'<', 1, 8, 256},
140 {'<', 1, 9, 512},
141 {'<', 1, 10, 1024},
142 {'<', 1, 11, 2048},
143 {'<', 1, 12, 4096},
144 {'<', 1, 13, 8192},
145 {'<', 1, 14, 16384},
146 {'<', 1, 15, 32768},
147 {'<', 1, 16, 65536},
148 {'<', 1, 17, 131072},
149 {'<', 1, 18, 262144},
150 {'<', 1, 19, 524288},
151 {'<', 1, 20, 1048576},
152 {'<', 0xdd, 0x18, 0xdd000000 },
153 {'<', 0x68, 0x02, 0x01a0 },
154 {'>', 0xf6, 1, 0x7b },
155 {'>', 0x1a, 1, 0x0d },
156 {'>', 0xb0, 1, 0x58 },
157 {'>', 0xba, 1, 0x5d },
158 {'>', 0x10, 3, 0x02 },
159 {'>', 0xe8, 4, 0x0e },
160 {'>', 0x37, 4, 0x03 },
161 {'>', 0xa0, 7, 0x01 },
162 {'>', 1, 0, 1},
163 {'>', 2, 1, 1},
164 {'>', 4, 2, 1},
165 {'>', 8, 3, 1},
166 {'>', 16, 4, 1},
167 {'>', 32, 5, 1},
168 {'>', 64, 6, 1},
169 {'>', 128, 7, 1},
170 {'>', 256, 8, 1},
171 {'>', 512, 9, 1},
172 {'>', 1024, 10, 1},
173 {'>', 2048, 11, 1},
174 {'>', 4096, 12, 1},
175 {'>', 8192, 13, 1},
176 {'>', 16384, 14, 1},
177 {'>', 32768, 15, 1},
178 {'>', 65536, 16, 1},
179 {'>', 131072, 17, 1},
180 {'>', 262144, 18, 1},
181 {'>', 524288, 19, 1},
182 {'>', 1048576, 20, 1},
183 };
184 const int ntests = sizeof(oracle) / sizeof(*oracle);
185
186
187
main()188 int main()
189 {
190 struct bn sa, sb, sc, sd;
191 uint32_t ia, ib, ic;
192 char op;
193 char buf[8192];
194 int npassed = 0;
195 int test_passed;
196
197 printf("\nRunning \"golden\" tests (parsed using from_int):\n\n");
198
199 int i;
200 for (i = 0; i < ntests; ++i)
201 {
202 /* Copy operator + operands from oracle */
203 op = oracle[i].op;
204 ia = oracle[i].a;
205 ib = oracle[i].b;
206 ic = oracle[i].c;
207
208 /* Initialize big-num structures: */
209 bignum_init(&sd); /* init result holder */
210 bignum_from_int(&sa, ia);
211 bignum_from_int(&sb, ib);
212 bignum_from_int(&sc, ic);
213
214 /* Perform calculation: */
215 switch (op)
216 {
217 case '+': bignum_add(&sa, &sb, &sd); break;
218 case '-': bignum_sub(&sa, &sb, &sd); break;
219 case '*': bignum_mul(&sa, &sb, &sd); break;
220 case '/': bignum_div(&sa, &sb, &sd); break;
221 case '%': bignum_mod(&sa, &sb, &sd); break;
222 case '&': bignum_and(&sa, &sb, &sd); break;
223 case '|': bignum_or (&sa, &sb, &sd); break;
224 case '^': bignum_xor(&sa, &sb, &sd); break;
225 case 'p': bignum_pow(&sa, &sb, &sd); break;
226 case '<': bignum_lshift(&sa, &sd, ib); break;
227 case '>': bignum_rshift(&sa, &sd, ib); break;
228
229 /* Crash program if operator is unsupported. */
230 default: require(0, "default switch-case hit");
231 }
232
233 /* Verify validity: */
234 test_passed = (bignum_cmp(&sc, &sd) == EQUAL);
235
236 /* Print status: */
237 if (op == 'p')
238 {
239 printf(" %s pow(%u, %u) = %u \n", (test_passed ? "[ OK ]" : "[FAIL]"), ia, ib, ic);
240 }
241 else if ((op == '<') || (op == '>'))
242 {
243 printf(" %s %u %c%c %u = %u \n", (test_passed ? "[ OK ]" : "[FAIL]"), ia, op, op, ib, ic);
244 }
245 else
246 {
247 printf(" %s %u %c %u = %u \n", (test_passed ? "[ OK ]" : "[FAIL]"), ia, op, ib, ic);
248 }
249
250 if (test_passed)
251 {
252 npassed += 1;
253 }
254 else
255 {
256 bignum_to_string(&sa, buf, sizeof(buf));
257 printf(" a = %s \n", buf);
258 bignum_to_string(&sb, buf, sizeof(buf));
259 printf(" b = %s \n", buf);
260 bignum_to_string(&sc, buf, sizeof(buf));
261 printf(" c = %s \n", buf);
262 bignum_to_string(&sd, buf, sizeof(buf));
263 printf(" d = %s \n", buf);
264 printf("\n");
265 }
266 }
267
268 printf("\n%d/%d tests successful.\n", npassed, ntests);
269
270
271 printf("\n");
272
273 return (ntests - npassed); /* 0 if all tests passed */
274 }
275
276