1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Promote 'testbn' to a binary built by the makefiles.

This makes it easier to compile in multiple debugging modes, or on
Windows, without having to constantly paste annoying test-compile
commands out of comments in sshbn.c.

The new binary is compiled into the build directory, but not shipped
by 'make install', just like fuzzterm. Unlike fuzzterm, though, testbn
is also compiled on Windows, for which we didn't already have a
mechanism for building unshipped binaries; I've done the very simplest
thing for the moment, of providing a target in Makefile.vc to delete
them.

In order to comply with the PuTTY makefile system's constraint of
never compiling the same object multiple times with different ifdefs,
I've also moved testbn's main() out into its own source file.
This commit is contained in:
Simon Tatham 2015-12-16 14:40:00 +00:00
parent 84cd309295
commit daeeca55a4
4 changed files with 277 additions and 267 deletions

View File

@ -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

11
Recipe
View File

@ -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

266
sshbn.c
View File

@ -2180,269 +2180,3 @@ char *bignum_decimal(Bignum x)
sfree(workspace);
return ret;
}
#ifdef TESTBN
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/*
* 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

265
testbn.c Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#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;
}