]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - testbn.c
first pass
[PuTTY.git] / testbn.c
1 /*
2  * testbn.c: standalone test program for the bignum code.
3  */
4
5 /*
6  * Accepts input on standard input, in the form generated by
7  * testdata/bignum.py.
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <ctype.h>
13
14 #include "ssh.h"
15 #include "sshbn.h"
16
17 void modalfatalbox(const char *p, ...)
18 {
19     va_list ap;
20     fprintf(stderr, "FATAL ERROR: ");
21     va_start(ap, p);
22     vfprintf(stderr, p, ap);
23     va_end(ap);
24     fputc('\n', stderr);
25     exit(1);
26 }
27
28 int random_byte(void)
29 {
30     modalfatalbox("random_byte called in testbn");
31     return 0;
32 }
33
34 #define fromxdigit(c) ( (c)>'9' ? ((c)&0xDF) - 'A' + 10 : (c) - '0' )
35
36 /* For Unix in particular, but harmless if this main() is reused elsewhere */
37 const int buildinfo_gtk_relevant = FALSE;
38
39 int main(int argc, char **argv)
40 {
41     char *buf;
42     int line = 0;
43     int passes = 0, fails = 0;
44
45     printf("BIGNUM_INT_BITS = %d\n", (int)BIGNUM_INT_BITS);
46
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;
51         int ptrnum;
52         char *bufp = buf;
53
54         line++;
55
56         q = data;
57         ptrnum = 0;
58
59         while (*bufp && !isspace((unsigned char)*bufp))
60             bufp++;
61         if (*bufp)
62             *bufp++ = '\0';
63
64         while (*bufp) {
65             char *start, *end;
66             int i;
67
68             while (*bufp && !isxdigit((unsigned char)*bufp))
69                 bufp++;
70             start = bufp;
71
72             if (!*bufp)
73                 break;
74
75             while (*bufp && isxdigit((unsigned char)*bufp))
76                 bufp++;
77             end = bufp;
78
79             if (ptrnum >= lenof(ptrs))
80                 break;
81             ptrs[ptrnum++] = q;
82             
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]);
86                 *q++ = val;
87             }
88         }
89
90         if (!strcmp(buf, "mul")) {
91             Bignum a, b, c, p;
92
93             if (ptrnum != 3) {
94                 printf("%d: mul with %d parameters, expected 3\n", line, ptrnum);
95                 exit(1);
96             }
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]);
100             p = bigmul(a, b);
101
102             if (bignum_cmp(c, p) == 0) {
103                 passes++;
104             } else {
105                 char *as = bignum_decimal(a);
106                 char *bs = bignum_decimal(b);
107                 char *cs = bignum_decimal(c);
108                 char *ps = bignum_decimal(p);
109                 
110                 printf("%d: fail: %s * %s gave %s expected %s\n",
111                        line, as, bs, ps, cs);
112                 fails++;
113
114                 sfree(as);
115                 sfree(bs);
116                 sfree(cs);
117                 sfree(ps);
118             }
119             freebn(a);
120             freebn(b);
121             freebn(c);
122             freebn(p);
123         } else if (!strcmp(buf, "modmul")) {
124             Bignum a, b, m, c, p;
125
126             if (ptrnum != 4) {
127                 printf("%d: modmul with %d parameters, expected 4\n",
128                        line, ptrnum);
129                 exit(1);
130             }
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]);
135             p = modmul(a, b, m);
136
137             if (bignum_cmp(c, p) == 0) {
138                 passes++;
139             } else {
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);
145                 
146                 printf("%d: fail: %s * %s mod %s gave %s expected %s\n",
147                        line, as, bs, ms, ps, cs);
148                 fails++;
149
150                 sfree(as);
151                 sfree(bs);
152                 sfree(ms);
153                 sfree(cs);
154                 sfree(ps);
155             }
156             freebn(a);
157             freebn(b);
158             freebn(m);
159             freebn(c);
160             freebn(p);
161         } else if (!strcmp(buf, "pow")) {
162             Bignum base, expt, modulus, expected, answer;
163
164             if (ptrnum != 4) {
165                 printf("%d: pow with %d parameters, expected 4\n", line, ptrnum);
166                 exit(1);
167             }
168
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);
174
175             if (bignum_cmp(expected, answer) == 0) {
176                 passes++;
177             } else {
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);
183                 
184                 printf("%d: fail: %s ^ %s mod %s gave %s expected %s\n",
185                        line, as, bs, cs, ds, ps);
186                 fails++;
187
188                 sfree(as);
189                 sfree(bs);
190                 sfree(cs);
191                 sfree(ds);
192                 sfree(ps);
193             }
194             freebn(base);
195             freebn(expt);
196             freebn(modulus);
197             freebn(expected);
198             freebn(answer);
199         } else if (!strcmp(buf, "divmod")) {
200             Bignum n, d, expect_q, expect_r, answer_q, answer_r;
201             int fail;
202
203             if (ptrnum != 4) {
204                 printf("%d: divmod with %d parameters, expected 4\n", line, ptrnum);
205                 exit(1);
206             }
207
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);
214
215             fail = FALSE;
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);
221
222                 printf("%d: fail: %s / %s gave %s expected %s\n",
223                        line, as, bs, cs, ds);
224                 fail = TRUE;
225
226                 sfree(as);
227                 sfree(bs);
228                 sfree(cs);
229                 sfree(ds);
230             }
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);
236
237                 printf("%d: fail: %s mod %s gave %s expected %s\n",
238                        line, as, bs, cs, ds);
239                 fail = TRUE;
240
241                 sfree(as);
242                 sfree(bs);
243                 sfree(cs);
244                 sfree(ds);
245             }
246
247             freebn(n);
248             freebn(d);
249             freebn(expect_q);
250             freebn(expect_r);
251             freebn(answer_q);
252             freebn(answer_r);
253
254             if (fail)
255                 fails++;
256             else
257                 passes++;
258         } else {
259             printf("%d: unrecognised test keyword: '%s'\n", line, buf);
260             exit(1);
261         }
262
263         sfree(buf);
264         sfree(data);
265     }
266
267     printf("passed %d failed %d total %d\n", passes, fails, passes+fails);
268     return fails != 0;
269 }