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