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