simon-git: putty (master): Simon Tatham
Commits to Tartarus CVS repository.
tartarus-commits at lists.tartarus.org
Sun Dec 13 14:55:28 GMT 2015
TL;DR:
90c7b15 Fix copy-and-paste error in testbn main program.
984792e Add direct tests of division/modulus to testbn.
482b4ab Rewrite the core divide function to not use DIVMOD_WORD.
Repository: git://git.tartarus.org/simon/putty.git
On the web: http://tartarus.org/~simon-git/gitweb/?p=putty.git
Branch updated: master
Committer: Simon Tatham <anakin at pobox.com>
Date: 2015-12-13 14:55:28
commit 90c7b1562ce540d38f688492543467cc4dfa983c
web diff http://tartarus.org/~simon-git/gitweb/?p=putty.git;a=commitdiff;h=90c7b1562ce540d38f688492543467cc4dfa983c;hp=d0e9630e1c2f880bb7cb7ae107685bd1a6d189c4
Author: Simon Tatham <anakin at pobox.com>
Date: Sun Dec 13 14:46:42 2015 +0000
Fix copy-and-paste error in testbn main program.
I called a 'pow' test line 'mul' in an error message.
sshbn.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
commit 984792e9f4523eec1505e83ab17b8f377f7db43d
web diff http://tartarus.org/~simon-git/gitweb/?p=putty.git;a=commitdiff;h=984792e9f4523eec1505e83ab17b8f377f7db43d;hp=90c7b1562ce540d38f688492543467cc4dfa983c
Author: Simon Tatham <anakin at pobox.com>
Date: Sun Dec 13 14:46:43 2015 +0000
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(+)
commit 482b4ab872cc4987bce862c8af0de1e9bfc4c696
web diff http://tartarus.org/~simon-git/gitweb/?p=putty.git;a=commitdiff;h=482b4ab872cc4987bce862c8af0de1e9bfc4c696;hp=984792e9f4523eec1505e83ab17b8f377f7db43d
Author: Simon Tatham <anakin at pobox.com>
Date: Sun Dec 13 14:46:43 2015 +0000
Rewrite the core divide function to not use DIVMOD_WORD.
DIVMOD_WORD is a portability hazard, because implementing it requires
either a way to get direct access to the x86 DIV instruction or
equivalent (be it inline assembler or a compiler intrinsic), or else
an integer type we can use as BignumDblInt. But I'm starting to think
about porting to 64-bit Visual Studio with a 64-bit BignumInt, and in
that situation neither of those options will be available.
I could write a piece of _out_-of-line x86-64 assembler in a separate
source file and put a function call in DIVMOD_WORD, but instead I've
decided to solve the problem in a more futureproof way: remove
DIVMOD_WORD totally and write a division function that doesn't need it
at all, solving not only today's porting headache but all future ones
in this area.
The new implementation works by precomputing (a good enough
approximation to) the leading word of the reciprocal of the modulus,
and then getting each word of quotient by multiplying by that
reciprocal, where we previously used DIVMOD_WORD to divide by the
leading word of the actual modulus. The reciprocal itself is computed
outside internal_mod() and passed in as a parameter, allowing me to
save time by only computing it once when I'm about to do a modpow.
To some extent this complicates the implementation: the advantage of
DIVMOD_WORD was that it yielded a full word q of quotient every time
it was used, so the subtraction of q*m from the input could be done in
a nicely word-aligned way. But the reciprocal multiply approach yields
_almost_ a full word of quotient, because you have to make the
reciprocal a bit short to avoid overflow at multiplication time. For a
start, this means we have to do fractionally more iterations of the
main loop; but more painfully, we can no longer depend on the
subtraction of q*m at every step being word-aligned, and instead we
have to be prepared to do it at any bit shift.
But the flip side is that once we've implemented that, the rest of the
algorithm becomes a lot less full of horrible special cases: in
particular, we can now completely throw away the horribleness at all
the call sites where we shift the modulus up by a fractional word to
set its top bit, and then have to do a little dance to get the last
few bits of quotient involving a second call to internal_mod.
So there are points both for and against the new implementation in
simplicity terms; but I think on balance it's more comprehensible than
the old one, and a quick timing test suggests it also ends up a touch
faster overall - the new testbn gets through the output of
testdata/bignum.py in 4.034s where the old one took 4.392s.
sshbn.c | 591 +++++++++++++++++++++++++++++++++++++++++++++++----------------
sshbn.h | 55 +-----
2 files changed, 444 insertions(+), 202 deletions(-)
More information about the tartarus-commits
mailing list