]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - testbn.c
Promote 'testbn' to a binary built by the makefiles.
[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
16 void modalfatalbox(const char *p, ...)
17 {
18     va_list ap;
19     fprintf(stderr, "FATAL ERROR: ");
20     va_start(ap, p);
21     vfprintf(stderr, p, ap);
22     va_end(ap);
23     fputc('\n', stderr);
24     exit(1);
25 }
26
27 int random_byte(void)
28 {
29     modalfatalbox("random_byte called in testbn");
30     return 0;
31 }
32
33 #define fromxdigit(c) ( (c)>'9' ? ((c)&0xDF) - 'A' + 10 : (c) - '0' )
34
35 int main(int argc, char **argv)
36 {
37     char *buf;
38     int line = 0;
39     int passes = 0, fails = 0;
40
41     while ((buf = fgetline(stdin)) != NULL) {
42         int maxlen = strlen(buf);
43         unsigned char *data = snewn(maxlen, unsigned char);
44         unsigned char *ptrs[5], *q;
45         int ptrnum;
46         char *bufp = buf;
47
48         line++;
49
50         q = data;
51         ptrnum = 0;
52
53         while (*bufp && !isspace((unsigned char)*bufp))
54             bufp++;
55         if (bufp)
56             *bufp++ = '\0';
57
58         while (*bufp) {
59             char *start, *end;
60             int i;
61
62             while (*bufp && !isxdigit((unsigned char)*bufp))
63                 bufp++;
64             start = bufp;
65
66             if (!*bufp)
67                 break;
68
69             while (*bufp && isxdigit((unsigned char)*bufp))
70                 bufp++;
71             end = bufp;
72
73             if (ptrnum >= lenof(ptrs))
74                 break;
75             ptrs[ptrnum++] = q;
76             
77             for (i = -((end - start) & 1); i < end-start; i += 2) {
78                 unsigned char val = (i < 0 ? 0 : fromxdigit(start[i]));
79                 val = val * 16 + fromxdigit(start[i+1]);
80                 *q++ = val;
81             }
82
83             ptrs[ptrnum] = q;
84         }
85
86         if (!strcmp(buf, "mul")) {
87             Bignum a, b, c, p;
88
89             if (ptrnum != 3) {
90                 printf("%d: mul with %d parameters, expected 3\n", line, ptrnum);
91                 exit(1);
92             }
93             a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
94             b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
95             c = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
96             p = bigmul(a, b);
97
98             if (bignum_cmp(c, p) == 0) {
99                 passes++;
100             } else {
101                 char *as = bignum_decimal(a);
102                 char *bs = bignum_decimal(b);
103                 char *cs = bignum_decimal(c);
104                 char *ps = bignum_decimal(p);
105                 
106                 printf("%d: fail: %s * %s gave %s expected %s\n",
107                        line, as, bs, ps, cs);
108                 fails++;
109
110                 sfree(as);
111                 sfree(bs);
112                 sfree(cs);
113                 sfree(ps);
114             }
115             freebn(a);
116             freebn(b);
117             freebn(c);
118             freebn(p);
119         } else if (!strcmp(buf, "modmul")) {
120             Bignum a, b, m, c, p;
121
122             if (ptrnum != 4) {
123                 printf("%d: modmul with %d parameters, expected 4\n",
124                        line, ptrnum);
125                 exit(1);
126             }
127             a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
128             b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
129             m = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
130             c = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);
131             p = modmul(a, b, m);
132
133             if (bignum_cmp(c, p) == 0) {
134                 passes++;
135             } else {
136                 char *as = bignum_decimal(a);
137                 char *bs = bignum_decimal(b);
138                 char *ms = bignum_decimal(m);
139                 char *cs = bignum_decimal(c);
140                 char *ps = bignum_decimal(p);
141                 
142                 printf("%d: fail: %s * %s mod %s gave %s expected %s\n",
143                        line, as, bs, ms, ps, cs);
144                 fails++;
145
146                 sfree(as);
147                 sfree(bs);
148                 sfree(ms);
149                 sfree(cs);
150                 sfree(ps);
151             }
152             freebn(a);
153             freebn(b);
154             freebn(m);
155             freebn(c);
156             freebn(p);
157         } else if (!strcmp(buf, "pow")) {
158             Bignum base, expt, modulus, expected, answer;
159
160             if (ptrnum != 4) {
161                 printf("%d: pow with %d parameters, expected 4\n", line, ptrnum);
162                 exit(1);
163             }
164
165             base = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
166             expt = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
167             modulus = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
168             expected = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);
169             answer = modpow(base, expt, modulus);
170
171             if (bignum_cmp(expected, answer) == 0) {
172                 passes++;
173             } else {
174                 char *as = bignum_decimal(base);
175                 char *bs = bignum_decimal(expt);
176                 char *cs = bignum_decimal(modulus);
177                 char *ds = bignum_decimal(answer);
178                 char *ps = bignum_decimal(expected);
179                 
180                 printf("%d: fail: %s ^ %s mod %s gave %s expected %s\n",
181                        line, as, bs, cs, ds, ps);
182                 fails++;
183
184                 sfree(as);
185                 sfree(bs);
186                 sfree(cs);
187                 sfree(ds);
188                 sfree(ps);
189             }
190             freebn(base);
191             freebn(expt);
192             freebn(modulus);
193             freebn(expected);
194             freebn(answer);
195         } else if (!strcmp(buf, "divmod")) {
196             Bignum n, d, expect_q, expect_r, answer_q, answer_r;
197             int fail;
198
199             if (ptrnum != 4) {
200                 printf("%d: divmod with %d parameters, expected 4\n", line, ptrnum);
201                 exit(1);
202             }
203
204             n = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
205             d = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
206             expect_q = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
207             expect_r = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);
208             answer_q = bigdiv(n, d);
209             answer_r = bigmod(n, d);
210
211             fail = FALSE;
212             if (bignum_cmp(expect_q, answer_q) != 0) {
213                 char *as = bignum_decimal(n);
214                 char *bs = bignum_decimal(d);
215                 char *cs = bignum_decimal(answer_q);
216                 char *ds = bignum_decimal(expect_q);
217
218                 printf("%d: fail: %s / %s gave %s expected %s\n",
219                        line, as, bs, cs, ds);
220                 fail = TRUE;
221
222                 sfree(as);
223                 sfree(bs);
224                 sfree(cs);
225                 sfree(ds);
226             }
227             if (bignum_cmp(expect_r, answer_r) != 0) {
228                 char *as = bignum_decimal(n);
229                 char *bs = bignum_decimal(d);
230                 char *cs = bignum_decimal(answer_r);
231                 char *ds = bignum_decimal(expect_r);
232
233                 printf("%d: fail: %s mod %s gave %s expected %s\n",
234                        line, as, bs, cs, ds);
235                 fail = TRUE;
236
237                 sfree(as);
238                 sfree(bs);
239                 sfree(cs);
240                 sfree(ds);
241             }
242
243             freebn(n);
244             freebn(d);
245             freebn(expect_q);
246             freebn(expect_r);
247             freebn(answer_q);
248             freebn(answer_r);
249
250             if (fail)
251                 fails++;
252             else
253                 passes++;
254         } else {
255             printf("%d: unrecognised test keyword: '%s'\n", line, buf);
256             exit(1);
257         }
258
259         sfree(buf);
260         sfree(data);
261     }
262
263     printf("passed %d failed %d total %d\n", passes, fails, passes+fails);
264     return fails != 0;
265 }