2 * testbn.c: standalone test program for the bignum code.
6 * Accepts input on standard input, in the form generated by
17 void modalfatalbox(const char *p, ...)
20 fprintf(stderr, "FATAL ERROR: ");
22 vfprintf(stderr, p, ap);
30 modalfatalbox("random_byte called in testbn");
34 #define fromxdigit(c) ( (c)>'9' ? ((c)&0xDF) - 'A' + 10 : (c) - '0' )
36 /* For Unix in particular, but harmless if this main() is reused elsewhere */
37 const int buildinfo_gtk_relevant = FALSE;
39 int main(int argc, char **argv)
43 int passes = 0, fails = 0;
45 printf("BIGNUM_INT_BITS = %d\n", (int)BIGNUM_INT_BITS);
47 while ((buf = fgetline(stdin)) != NULL) {
48 int maxlen = strlen(buf);
49 unsigned char *data = snewn(maxlen, unsigned char);
50 unsigned char *ptrs[5], *q;
59 while (*bufp && !isspace((unsigned char)*bufp))
68 while (*bufp && !isxdigit((unsigned char)*bufp))
75 while (*bufp && isxdigit((unsigned char)*bufp))
79 if (ptrnum >= lenof(ptrs))
83 for (i = -((end - start) & 1); i < end-start; i += 2) {
84 unsigned char val = (i < 0 ? 0 : fromxdigit(start[i]));
85 val = val * 16 + fromxdigit(start[i+1]);
90 if (!strcmp(buf, "mul")) {
94 printf("%d: mul with %d parameters, expected 3\n", line, ptrnum);
97 a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
98 b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
99 c = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
102 if (bignum_cmp(c, p) == 0) {
105 char *as = bignum_decimal(a);
106 char *bs = bignum_decimal(b);
107 char *cs = bignum_decimal(c);
108 char *ps = bignum_decimal(p);
110 printf("%d: fail: %s * %s gave %s expected %s\n",
111 line, as, bs, ps, cs);
123 } else if (!strcmp(buf, "modmul")) {
124 Bignum a, b, m, c, p;
127 printf("%d: modmul with %d parameters, expected 4\n",
131 a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
132 b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
133 m = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
134 c = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);
137 if (bignum_cmp(c, p) == 0) {
140 char *as = bignum_decimal(a);
141 char *bs = bignum_decimal(b);
142 char *ms = bignum_decimal(m);
143 char *cs = bignum_decimal(c);
144 char *ps = bignum_decimal(p);
146 printf("%d: fail: %s * %s mod %s gave %s expected %s\n",
147 line, as, bs, ms, ps, cs);
161 } else if (!strcmp(buf, "pow")) {
162 Bignum base, expt, modulus, expected, answer;
165 printf("%d: pow with %d parameters, expected 4\n", line, ptrnum);
169 base = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
170 expt = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
171 modulus = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
172 expected = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);
173 answer = modpow(base, expt, modulus);
175 if (bignum_cmp(expected, answer) == 0) {
178 char *as = bignum_decimal(base);
179 char *bs = bignum_decimal(expt);
180 char *cs = bignum_decimal(modulus);
181 char *ds = bignum_decimal(answer);
182 char *ps = bignum_decimal(expected);
184 printf("%d: fail: %s ^ %s mod %s gave %s expected %s\n",
185 line, as, bs, cs, ds, ps);
199 } else if (!strcmp(buf, "divmod")) {
200 Bignum n, d, expect_q, expect_r, answer_q, answer_r;
204 printf("%d: divmod with %d parameters, expected 4\n", line, ptrnum);
208 n = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
209 d = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
210 expect_q = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
211 expect_r = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);
212 answer_q = bigdiv(n, d);
213 answer_r = bigmod(n, d);
216 if (bignum_cmp(expect_q, answer_q) != 0) {
217 char *as = bignum_decimal(n);
218 char *bs = bignum_decimal(d);
219 char *cs = bignum_decimal(answer_q);
220 char *ds = bignum_decimal(expect_q);
222 printf("%d: fail: %s / %s gave %s expected %s\n",
223 line, as, bs, cs, ds);
231 if (bignum_cmp(expect_r, answer_r) != 0) {
232 char *as = bignum_decimal(n);
233 char *bs = bignum_decimal(d);
234 char *cs = bignum_decimal(answer_r);
235 char *ds = bignum_decimal(expect_r);
237 printf("%d: fail: %s mod %s gave %s expected %s\n",
238 line, as, bs, cs, ds);
259 printf("%d: unrecognised test keyword: '%s'\n", line, buf);
267 printf("passed %d failed %d total %d\n", passes, fails, passes+fails);