From 984792e9f4523eec1505e83ab17b8f377f7db43d Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 13 Dec 2015 14:46:43 +0000 Subject: [PATCH] Add direct tests of division/modulus to testbn. I'm about to rewrite the division code, so it'll be useful to have a way to test it directly, particularly one which exercises difficult cases such as extreme values of the leading word and remainders just above and below zero. --- sshbn.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ testdata/bignum.py | 15 ++++++++++++ 2 files changed, 74 insertions(+) diff --git a/sshbn.c b/sshbn.c index afc38a0b..c9859093 100644 --- a/sshbn.c +++ b/sshbn.c @@ -2059,6 +2059,65 @@ int main(int argc, char **argv) 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); diff --git a/testdata/bignum.py b/testdata/bignum.py index b2a6614b..15ffe319 100644 --- a/testdata/bignum.py +++ b/testdata/bignum.py @@ -103,6 +103,21 @@ for i in range(1,4200): a, b, p = findprod((1<= 0 + print "divmod", hexstr(n), hexstr(d), hexstr(n/d), hexstr(n%d) + # Simple tests of modmul. for ai in range(20, 200, 60): a = sqrt(3<<(2*ai-1))