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:
parent
84cd309295
commit
daeeca55a4
2
Buildscr
2
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
|
||||
|
11
Recipe
11
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
|
||||
|
266
sshbn.c
266
sshbn.c
@ -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
265
testbn.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user