diff --git a/Buildscr b/Buildscr index c9420658..84dda5c7 100644 --- a/Buildscr +++ b/Buildscr @@ -150,7 +150,7 @@ in putty do perl -i~ -pe 'y/\015//d;s/$$/\015/' LICENCE delegate windows # FIXME: Cygwin alternative? - in putty/windows do/win vcvars32 && nmake -f Makefile.vc $(Makeargs) + in putty/windows do/win vcvars32 && nmake -f Makefile.vc $(Makeargs) all cleantestprogs # Code-sign the binaries, if the local bob config provides a script # to do so. We assume here that the script accepts an -i option to # provide a 'more info' URL, and an optional -n option to provide a diff --git a/Recipe b/Recipe index fc8e444a..0d119d13 100644 --- a/Recipe +++ b/Recipe @@ -323,3 +323,14 @@ PuTTY : [MX] osxmain OSXTERM OSXMISC CHARSET U_BE_ALL NONSSH UXSSH fuzzterm : [UT] UXTERM CHARSET misc uxmisc uxucs fuzzterm time settings + uxstore be_none +testbn : [UT] testbn sshbn misc conf tree234 uxmisc +testbn : [C] testbn sshbn misc conf tree234 winmisc LIBS + +# ---------------------------------------------------------------------- +# On Windows, provide a means of removing local test binaries that we +# aren't going to actually ship. (I prefer this to not building them +# in the first place, so that we find out about build breakage early.) +!begin vc +cleantestprogs: + -del testbn.exe +!end diff --git a/sshbn.c b/sshbn.c index 4f27dc9b..724cf301 100644 --- a/sshbn.c +++ b/sshbn.c @@ -2180,269 +2180,3 @@ char *bignum_decimal(Bignum x) sfree(workspace); return ret; } - -#ifdef TESTBN - -#include -#include -#include - -/* - * gcc -Wall -g -O0 -DTESTBN -o testbn sshbn.c misc.c conf.c tree234.c unix/uxmisc.c -I. -I unix -I charset - * - * Then feed to this program's standard input the output of - * testdata/bignum.py . - */ - -void modalfatalbox(const char *p, ...) -{ - va_list ap; - fprintf(stderr, "FATAL ERROR: "); - va_start(ap, p); - vfprintf(stderr, p, ap); - va_end(ap); - fputc('\n', stderr); - exit(1); -} - -int random_byte(void) -{ - modalfatalbox("random_byte called in testbn"); - return 0; -} - -#define fromxdigit(c) ( (c)>'9' ? ((c)&0xDF) - 'A' + 10 : (c) - '0' ) - -int main(int argc, char **argv) -{ - char *buf; - int line = 0; - int passes = 0, fails = 0; - - while ((buf = fgetline(stdin)) != NULL) { - int maxlen = strlen(buf); - unsigned char *data = snewn(maxlen, unsigned char); - unsigned char *ptrs[5], *q; - int ptrnum; - char *bufp = buf; - - line++; - - q = data; - ptrnum = 0; - - while (*bufp && !isspace((unsigned char)*bufp)) - bufp++; - if (bufp) - *bufp++ = '\0'; - - while (*bufp) { - char *start, *end; - int i; - - while (*bufp && !isxdigit((unsigned char)*bufp)) - bufp++; - start = bufp; - - if (!*bufp) - break; - - while (*bufp && isxdigit((unsigned char)*bufp)) - bufp++; - end = bufp; - - if (ptrnum >= lenof(ptrs)) - break; - ptrs[ptrnum++] = q; - - for (i = -((end - start) & 1); i < end-start; i += 2) { - unsigned char val = (i < 0 ? 0 : fromxdigit(start[i])); - val = val * 16 + fromxdigit(start[i+1]); - *q++ = val; - } - - ptrs[ptrnum] = q; - } - - if (!strcmp(buf, "mul")) { - Bignum a, b, c, p; - - if (ptrnum != 3) { - printf("%d: mul with %d parameters, expected 3\n", line, ptrnum); - exit(1); - } - a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); - b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); - c = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); - p = bigmul(a, b); - - if (bignum_cmp(c, p) == 0) { - passes++; - } else { - char *as = bignum_decimal(a); - char *bs = bignum_decimal(b); - char *cs = bignum_decimal(c); - char *ps = bignum_decimal(p); - - printf("%d: fail: %s * %s gave %s expected %s\n", - line, as, bs, ps, cs); - fails++; - - sfree(as); - sfree(bs); - sfree(cs); - sfree(ps); - } - freebn(a); - freebn(b); - freebn(c); - freebn(p); - } else if (!strcmp(buf, "modmul")) { - Bignum a, b, m, c, p; - - if (ptrnum != 4) { - printf("%d: modmul with %d parameters, expected 4\n", - line, ptrnum); - exit(1); - } - a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); - b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); - m = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); - c = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]); - p = modmul(a, b, m); - - if (bignum_cmp(c, p) == 0) { - passes++; - } else { - char *as = bignum_decimal(a); - char *bs = bignum_decimal(b); - char *ms = bignum_decimal(m); - char *cs = bignum_decimal(c); - char *ps = bignum_decimal(p); - - printf("%d: fail: %s * %s mod %s gave %s expected %s\n", - line, as, bs, ms, ps, cs); - fails++; - - sfree(as); - sfree(bs); - sfree(ms); - sfree(cs); - sfree(ps); - } - freebn(a); - freebn(b); - freebn(m); - freebn(c); - freebn(p); - } else if (!strcmp(buf, "pow")) { - Bignum base, expt, modulus, expected, answer; - - if (ptrnum != 4) { - printf("%d: pow with %d parameters, expected 4\n", line, ptrnum); - exit(1); - } - - base = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); - expt = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); - modulus = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); - expected = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]); - answer = modpow(base, expt, modulus); - - if (bignum_cmp(expected, answer) == 0) { - passes++; - } else { - char *as = bignum_decimal(base); - char *bs = bignum_decimal(expt); - char *cs = bignum_decimal(modulus); - char *ds = bignum_decimal(answer); - char *ps = bignum_decimal(expected); - - printf("%d: fail: %s ^ %s mod %s gave %s expected %s\n", - line, as, bs, cs, ds, ps); - fails++; - - sfree(as); - sfree(bs); - sfree(cs); - sfree(ds); - sfree(ps); - } - freebn(base); - freebn(expt); - freebn(modulus); - freebn(expected); - freebn(answer); - } else if (!strcmp(buf, "divmod")) { - Bignum n, d, expect_q, expect_r, answer_q, answer_r; - int fail; - - if (ptrnum != 4) { - printf("%d: divmod with %d parameters, expected 4\n", line, ptrnum); - exit(1); - } - - n = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); - d = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); - expect_q = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); - expect_r = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]); - answer_q = bigdiv(n, d); - answer_r = bigmod(n, d); - - fail = FALSE; - if (bignum_cmp(expect_q, answer_q) != 0) { - char *as = bignum_decimal(n); - char *bs = bignum_decimal(d); - char *cs = bignum_decimal(answer_q); - char *ds = bignum_decimal(expect_q); - - printf("%d: fail: %s / %s gave %s expected %s\n", - line, as, bs, cs, ds); - fail = TRUE; - - sfree(as); - sfree(bs); - sfree(cs); - sfree(ds); - } - if (bignum_cmp(expect_r, answer_r) != 0) { - char *as = bignum_decimal(n); - char *bs = bignum_decimal(d); - char *cs = bignum_decimal(answer_r); - char *ds = bignum_decimal(expect_r); - - printf("%d: fail: %s mod %s gave %s expected %s\n", - line, as, bs, cs, ds); - fail = TRUE; - - sfree(as); - sfree(bs); - sfree(cs); - sfree(ds); - } - - freebn(n); - freebn(d); - freebn(expect_q); - freebn(expect_r); - freebn(answer_q); - freebn(answer_r); - - if (fail) - fails++; - else - passes++; - } else { - printf("%d: unrecognised test keyword: '%s'\n", line, buf); - exit(1); - } - - sfree(buf); - sfree(data); - } - - printf("passed %d failed %d total %d\n", passes, fails, passes+fails); - return fails != 0; -} - -#endif diff --git a/testbn.c b/testbn.c new file mode 100644 index 00000000..55471bd2 --- /dev/null +++ b/testbn.c @@ -0,0 +1,265 @@ +/* + * testbn.c: standalone test program for the bignum code. + */ + +/* + * Accepts input on standard input, in the form generated by + * testdata/bignum.py. + */ + +#include +#include +#include + +#include "ssh.h" + +void modalfatalbox(const char *p, ...) +{ + va_list ap; + fprintf(stderr, "FATAL ERROR: "); + va_start(ap, p); + vfprintf(stderr, p, ap); + va_end(ap); + fputc('\n', stderr); + exit(1); +} + +int random_byte(void) +{ + modalfatalbox("random_byte called in testbn"); + return 0; +} + +#define fromxdigit(c) ( (c)>'9' ? ((c)&0xDF) - 'A' + 10 : (c) - '0' ) + +int main(int argc, char **argv) +{ + char *buf; + int line = 0; + int passes = 0, fails = 0; + + while ((buf = fgetline(stdin)) != NULL) { + int maxlen = strlen(buf); + unsigned char *data = snewn(maxlen, unsigned char); + unsigned char *ptrs[5], *q; + int ptrnum; + char *bufp = buf; + + line++; + + q = data; + ptrnum = 0; + + while (*bufp && !isspace((unsigned char)*bufp)) + bufp++; + if (bufp) + *bufp++ = '\0'; + + while (*bufp) { + char *start, *end; + int i; + + while (*bufp && !isxdigit((unsigned char)*bufp)) + bufp++; + start = bufp; + + if (!*bufp) + break; + + while (*bufp && isxdigit((unsigned char)*bufp)) + bufp++; + end = bufp; + + if (ptrnum >= lenof(ptrs)) + break; + ptrs[ptrnum++] = q; + + for (i = -((end - start) & 1); i < end-start; i += 2) { + unsigned char val = (i < 0 ? 0 : fromxdigit(start[i])); + val = val * 16 + fromxdigit(start[i+1]); + *q++ = val; + } + + ptrs[ptrnum] = q; + } + + if (!strcmp(buf, "mul")) { + Bignum a, b, c, p; + + if (ptrnum != 3) { + printf("%d: mul with %d parameters, expected 3\n", line, ptrnum); + exit(1); + } + a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); + b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); + c = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); + p = bigmul(a, b); + + if (bignum_cmp(c, p) == 0) { + passes++; + } else { + char *as = bignum_decimal(a); + char *bs = bignum_decimal(b); + char *cs = bignum_decimal(c); + char *ps = bignum_decimal(p); + + printf("%d: fail: %s * %s gave %s expected %s\n", + line, as, bs, ps, cs); + fails++; + + sfree(as); + sfree(bs); + sfree(cs); + sfree(ps); + } + freebn(a); + freebn(b); + freebn(c); + freebn(p); + } else if (!strcmp(buf, "modmul")) { + Bignum a, b, m, c, p; + + if (ptrnum != 4) { + printf("%d: modmul with %d parameters, expected 4\n", + line, ptrnum); + exit(1); + } + a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); + b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); + m = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); + c = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]); + p = modmul(a, b, m); + + if (bignum_cmp(c, p) == 0) { + passes++; + } else { + char *as = bignum_decimal(a); + char *bs = bignum_decimal(b); + char *ms = bignum_decimal(m); + char *cs = bignum_decimal(c); + char *ps = bignum_decimal(p); + + printf("%d: fail: %s * %s mod %s gave %s expected %s\n", + line, as, bs, ms, ps, cs); + fails++; + + sfree(as); + sfree(bs); + sfree(ms); + sfree(cs); + sfree(ps); + } + freebn(a); + freebn(b); + freebn(m); + freebn(c); + freebn(p); + } else if (!strcmp(buf, "pow")) { + Bignum base, expt, modulus, expected, answer; + + if (ptrnum != 4) { + printf("%d: pow with %d parameters, expected 4\n", line, ptrnum); + exit(1); + } + + base = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); + expt = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); + modulus = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); + expected = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]); + answer = modpow(base, expt, modulus); + + if (bignum_cmp(expected, answer) == 0) { + passes++; + } else { + char *as = bignum_decimal(base); + char *bs = bignum_decimal(expt); + char *cs = bignum_decimal(modulus); + char *ds = bignum_decimal(answer); + char *ps = bignum_decimal(expected); + + printf("%d: fail: %s ^ %s mod %s gave %s expected %s\n", + line, as, bs, cs, ds, ps); + fails++; + + sfree(as); + sfree(bs); + sfree(cs); + sfree(ds); + sfree(ps); + } + freebn(base); + freebn(expt); + freebn(modulus); + freebn(expected); + freebn(answer); + } else if (!strcmp(buf, "divmod")) { + Bignum n, d, expect_q, expect_r, answer_q, answer_r; + int fail; + + if (ptrnum != 4) { + printf("%d: divmod with %d parameters, expected 4\n", line, ptrnum); + exit(1); + } + + n = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]); + d = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]); + expect_q = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]); + expect_r = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]); + answer_q = bigdiv(n, d); + answer_r = bigmod(n, d); + + fail = FALSE; + if (bignum_cmp(expect_q, answer_q) != 0) { + char *as = bignum_decimal(n); + char *bs = bignum_decimal(d); + char *cs = bignum_decimal(answer_q); + char *ds = bignum_decimal(expect_q); + + printf("%d: fail: %s / %s gave %s expected %s\n", + line, as, bs, cs, ds); + fail = TRUE; + + sfree(as); + sfree(bs); + sfree(cs); + sfree(ds); + } + if (bignum_cmp(expect_r, answer_r) != 0) { + char *as = bignum_decimal(n); + char *bs = bignum_decimal(d); + char *cs = bignum_decimal(answer_r); + char *ds = bignum_decimal(expect_r); + + printf("%d: fail: %s mod %s gave %s expected %s\n", + line, as, bs, cs, ds); + fail = TRUE; + + sfree(as); + sfree(bs); + sfree(cs); + sfree(ds); + } + + freebn(n); + freebn(d); + freebn(expect_q); + freebn(expect_r); + freebn(answer_q); + freebn(answer_r); + + if (fail) + fails++; + else + passes++; + } else { + printf("%d: unrecognised test keyword: '%s'\n", line, buf); + exit(1); + } + + sfree(buf); + sfree(data); + } + + printf("passed %d failed %d total %d\n", passes, fails, passes+fails); + return fails != 0; +}