changeset 1733:d529a52b2f7c coverity coverity

merge coverity from main
author Matt Johnston <matt@ucc.asn.au>
date Fri, 26 Jun 2020 21:07:34 +0800
parents b59623a64678 (current diff) 2f5d797d9811 (diff)
children
files .travis.yml Makefile.in default_options.h
diffstat 422 files changed, 17327 insertions(+), 48883 deletions(-) [+]
line wrap: on
line diff
--- a/.gitignore	Thu Mar 21 23:28:59 2019 +0800
+++ b/.gitignore	Fri Jun 26 21:07:34 2020 +0800
@@ -5,6 +5,7 @@
 *.bb
 *.bbg
 *.prof
+.*.swp
 /autom4te.cache
 /config.log
 /config.status
@@ -13,6 +14,9 @@
 /dropbearconvert
 /dropbearkey
 /dropbearmulti
+/fuzzcorpus
+/fuzzer-*
+/fuzzer-*.options
 /scp
 /scp-progress
 Makefile
@@ -20,3 +24,4 @@
 config.h.in
 configure
 default_options_guard.h
+tags
--- a/.hgsigs	Thu Mar 21 23:28:59 2019 +0800
+++ b/.hgsigs	Fri Jun 26 21:07:34 2020 +0800
@@ -24,3 +24,6 @@
 9030ffdbe5625e35ed7189ab84a41dfc8d413e9c 0 iQIcBAABCgAGBQJXkOg0AAoJEESTFJTynGdzc1kP/3vSKCnhOOvjCjnpTQadYcCUq8vTNnfLHYVu0R4ItPa/jT6RmxoaYP+lZnLnnBx9+aX7kzwHsa9BUX3MbMEyLrOzX2I+bDJbNPhQyupyCuPYlf5Q9KVcO9YlpbsC4q5XBzCn3j2+pT8kSfi9uD8fgY3TgE4w9meINrfQAealfjwMLT8S/I49/ni0r+usSfk/dnSShJYDUO7Ja0VWbJea/GkkZTu30bCnMUZPjRApipU3hPP63WFjkSMT1rp2mAXbWqyr9lf8z32yxzM9nMSjq4ViRFzFlkGtE3EVRJ4PwkO7JuiWAMPJpiQcEr+r52cCsmWhiGyHuINo01MwoMO9/n6uL1WVa3mJcE9se3xBOvfgDu2FRFGCAdm1tef+AGVo9EG1uJXi0sX2yUc6DMeuYaRWrXMMlZh7zp9cuNU9Y/lLui9RFmq66yeXG3Z2B72doju3Ig5QGrNNw2AOsSzeHdAtOp6ychqPcl9QfIeJQG18KyPSefZKM3G8YRKBRIwXFEH6iZJe5ZIP4iXrHDMn2JqtTRtDqKR8VNDAgb9z4Ffx8QRxFyj5JzTTMM1GddHb9udLvTQlO0ULYG7hCSMRNzvUBE2aTw8frjLRyfyyg3QpDu/hz8op8s1ecE8rTCD8RuX9DiiylNozypPtGNS+UDbAmkc1PCWaRpPVl+9K6787
 5c9207ceedaea794f958224c19214d66af6e2d56 0 iQIzBAABCgAdFiEE9zR+8u4uB6JnYoypRJMUlPKcZ3MFAlkdtooACgkQRJMUlPKcZ3P6ZxAAmLy/buZB/d96DJF/pViRWt/fWdjQFC4MqWfeSLW02OZ8Qkm1vPL3ln6WPHC2thy3xZWVg2uan3pLk/XXnsIFu8Q7r1EAfFFpvlMUmdl7asE8V6ilaeqmiI7bIvGMFbf4cZkQliLjiFkJX56tFHRCNi+rb7WgRuru3/GzPXUq2AvXZvFpFJgik0B72TxVlmCKeBRZq1FvP0UhAH48RJWYJksdEyzh2paMfjX9ZO5Q2SFFrmPw6k2ArdJFC1AYcgceZC84y06RKJ0WiSntUPlEUXgQbQVVWbtQDhjfJXMr/beuroNdT/vsRraLVkAzvhaDXNnHlAJNLQxci+AcLpnzZhxMW+ax7RRtrpXGxRN4cs0lBGUcSkaDybFqMYXwEjXAE8w6fdJRWCIlxctkAW/iNEO4kAG97hI2Qwcw5oU2Ymnv09zyGR+XJE35pJqPulJHExdwanJHvmjH0QF7TNFS82yxS5dKnP954cj3Lu9SWGYWjxQJRmLtOwb+lqqol4VTxG7Ois4uef9/Tpp9skeMZXVeNlpn2wrp6iFcX3uiiVDg9VKkl3ig6UqCiqQSuiIN87RXwUOeHXlCnW3adz3Xei0ziBrwLSql7lBIHGEAlUUNmJ3CrR8IwQtcynGEMKfNIeZ/XK+uNlm9cJIqZf1fzqc8KexlyS9AS0i/kiYZTr4=
 2f0c3f3361d3ea4eb9129ed8810699fda7e7a8ee 0 iQIzBAABCgAdFiEE9zR+8u4uB6JnYoypRJMUlPKcZ3MFAlqVb+IACgkQRJMUlPKcZ3OENA//R9HsOUJQB2QZjRgAvqgLn2AMLUvmWb2etTZEc3Nps957Fw1F4kjh6VGfIpWuytfsDx1W8qRx09ikTdb3YteMWCuX8/aFreSPrioYmzrAEcxkZdA7B/jciqU0iXuHiJ9saKk5TR70aNp+iRy0hjAgiYEsVMF9YKHzULOJcHr70x9XVKquubQkwNqJA+/b2JbK2j46wM5nVK/alGSI2kMmEzXmAHQxsvf1OLMvgH8ou/l0xsg/CuFEK299XKfZAbsFEXrjuoWZ1aSa6rTeOWsWli5T+czyyJHI4Eu0Sz/gaR8+MPhJSYes8YjvzEdv32rRMDVOdBq4e+HoTgFt/THYABP6/R1H5fX3Lm4K8u9F9SwJbb/YKRAIrfWDob8ApnGFHk2dyYO20Fskbbg6b1pC7ulDWsufu8lYkQyMlTc3dR6P4eTB6mKO4x+gMG6tIYZ60fiULoEnMJCgegPtevmz+TG1rzdjh3ljiw9Dxz5lNtL+W7sBKKHwhyG0u+bavgmvBMKNL/rdHEM+0yCIz1U6Lb8sVaST1E4zbdm7cWHbSozBij3G0GBSkLFEq7ZLlh8wco9rELRh0Y9fFsWY9j6H/PTOu0GfHrYluFb9WGywHAquQY8j2croRx+MrvTbR1wZrbevPNm9gqk3vgOiDWu7KwxLLqcj+dEQ7tccptVYtbM=
+07b0d56d186d7eeef4106137a3eba554959ba0e3 0 iQIzBAABCgAdFiEE9zR+8u4uB6JnYoypRJMUlPKcZ3MFAlyWOo8ACgkQRJMUlPKcZ3O+MQ//c5oeDUvZuFiI4FHZqfIK/59YAciTP+9TQmoWDVSuOdkd9ZYJA7b7DCusqP2TWFEIl9M7i5hTLTMD21xuEQQtfOSP6EXpUw6JNdh/lsJs7EDlFANtwkdEozAQozFKnXbJEV3y9WldEWUlmPFjt4fJQIuG10SU7MTJHcSaQddJCh3I1//F4EvgRe+OqyrFwKekGiFdvfjcIFN3lQmk6K1Sc0MgyIO/VVZm/AQpBi0Dlg0yOl+EDcxxlmeSInbvLceWSP6op35I4dE5YWH1UetjzIsr5AIM15/k3viAKDDefY1EMAzK9b7YAF4BLw0a6XoQu0apvcWaALE/bJzWNSg/QbCm2JAZzk21WLLvR+AELzPfKXrHX3o0h51lpQ4rs7EWKUm43dJPoWkcFNOU+BDsNzffcJgChbRs48ut89DYLiGmSxhRxE77VPbA+klgTGdctOTLd8psseRlGYCuGe8zeota80bV9fUZ9WJZHwNgEWGowKUoTjy6l5k9OH3iQuQX3OXoy78ufRgWDulE7noVTMhXurQ8a0Jf2k/MW9dcnqGVkWitCFKPEvZwVmWyW2AWsdMcBJnFFGzDsNSxWTtCF9XcxieDO1IB8vGwYcb1TwEVuVzvR/wwvc3PgVikF+4Qv2NqdoQc1yn2PkocY2hwXyIZUAwz7erNumlTbeC/JK8=
+ebcdb893992d286d363e60f5353d6e1401e7084b 0 iQIzBAABCgAdFiEE9zR+8u4uB6JnYoypRJMUlPKcZ3MFAlybhXAACgkQRJMUlPKcZ3O7pQ//QuNJfBVa7ROaOJOR2H/xr6PRn1Fnc6rr/GCF9cqWrbGP6wNo24dRjcu5LxviqPvzfwRXIMXwVz8L/y61/sm6XcA7VFP4+MBoltfeUOdMbfBdtwEUo3WMBdP1w2q5GgYj8ZY6MawiLEqFba5aua7dokTNBOQM3Yebj+9I16MiWEaRSnuwYPoieHW2Fo6oftcIgs/GCXwT2xYzc0n3FpYAbK7u6sEkpL16EstV0Y/G70+X1/4Mg3GM96S5fl9Zbun47W7/+gT4AQVQjE+UnPNDudObAe+2BaOZLFvEbd7iJBBcqtjpBktuP58IEAb3A3srUCy49LNLWk43lj+PtoslK/U6TShKQ2vAgfd//bbn6ieXFJY8N+wYPpJo1m7zpTiEtS7J7wu6vkGGZlqUAj6MHXZj223CgazhSAlg/XFPs9oz3Y96c33Tnd4jB9iEXNNt5jzCAMImx2huSGgnP0JFAbcniq/ug5tl1VWaracvSuJl7fmf17DbmehsLbvtZBoMlePY7Ssfb5IokfVvptt4zRpRZnjtWfHCjtC6zYhtvXTmXH/bqWwx9MMjOf5WPfZoCMvXfMqdVI15FVbxU15WnqjvdvKUCkdz1aMFzxqc4MXgyvjtB9CvO/8WwBOJ2m2nDdiZfh8/H8SawYqEHgB61FX5xA5aXecgXcjQnqWDDxw=
+4877afd51e041eca7749cc46b57fd80aa23815b4 0 iQIzBAABCgAdFiEE9zR+8u4uB6JnYoypRJMUlPKcZ3MFAl7nmREACgkQRJMUlPKcZ3PG1BAAnUl0/nTnQ3CMM3S72DT1JQ1eDxZa14r6r1xEPngU83hNNzmPcnfiMDts+Vz1M3PLxNNOXVVt/MTw04+V9joPhhSWEe8O1pd3lAqTPswL7hhIEbVwZwyFCuAV4iAm+tHKzKLjtjgZfMgij6XylOmw18VBw5R+suoOMclJqeHlJ5m0Mq2wRLDE+RdVCAkulTqhGYjJNQUXMMNPx/cxUo3NHsto9pWL3d1285vBByP6BQSaeYlO012InvJRlQuEkK3lnIyzq6voIc6+tMli0q9iyBz+2GIloBQNAnb6EGaXxqAOBW5NRc+/Oauiu8Yf/6JoFlkAIcPXmGRtxiAiynJImhiTaCFdgdxaXLFzjBvq+tcwVXvvNM52fOZ4Z3QgMDu6EgNWfma0lsg4T3ar2ml2/evuWeLVut5ZmYFHarTFX+/pTVy9nAZK/F5ROJM1prTNYI18PZV4qvULta8spGV2Be0rCkQQubp9RWdKHNGZE70lrX5OnNIwE/D3g2QE04243i0IGBwhlDEpYjqujLyHk8W6XE1CORx0hQ0fUjzKZsRvOB7XyMAFpQUVOhoMFcnk5XHDW6B/U7NAxzqNqO+gbHO/UIeuy/KOVlMNJCmtRL/HYNGZ6SCZbRpyX3d8Ow0sasNfJkZrT6a0Tf6lZktWOxtPkoEDLfuCzudzn4JxGQM=
--- a/.hgtags	Thu Mar 21 23:28:59 2019 +0800
+++ b/.hgtags	Fri Jun 26 21:07:34 2020 +0800
@@ -56,3 +56,6 @@
 0ed3d2bbf956cb8a9bf0f4b5a86b7dd9688205cb DROPBEAR_2016.74
 c31276613181c5cff7854e7ef586ace03424e55e DROPBEAR_2017.75
 1c66ca4f3791c82501c88e7637312182c7294978 DROPBEAR_2018.76
+6d1bbe7d5fa5827c7eae28bca044d691f7efa785 DROPBEAR_2019.77
+009d52ae26d35f3381c801e02318fa9be34be93c DROPBEAR_2019.78
+e2e4929d057b09422f2ea4556fb64209aff58161 DROPBEAR_2020.79
--- a/.travis.yml	Thu Mar 21 23:28:59 2019 +0800
+++ b/.travis.yml	Fri Jun 26 21:07:34 2020 +0800
@@ -1,13 +1,8 @@
 language: c
 
-os:
-  - linux
+git:
+  depth: 3
 
-compiler:
-  - gcc
-
-# container-based builds
-sudo: false
 addons:
   apt:
     packages:
--- a/CHANGES	Thu Mar 21 23:28:59 2019 +0800
+++ b/CHANGES	Fri Jun 26 21:07:34 2020 +0800
@@ -1,3 +1,117 @@
+2020.80 - 26 June 2020
+
+- Don't block authorized_keys logins with no-X11-forwarding or no-agent-forwarding 
+  restrictions when X11 or agent forwarding are disabled at compile time.
+  This is more of a problem now X11 is disabled by default, reported by Guilhem Moulin
+
+- Reduce binary size by 4kB (x64) when using bundled libtommath
+
+- Define GNU_SOURCE for getrandom() on uclibc, reported by Laurent Bercot and
+  Fabrice Fontaine
+
+- Improve checking libtomcrypt version compatibility
+
+- Add some style notes to DEVELOPING.md
+
+2020.79 - 15 June 2020
+
+- Support ed25519 hostkeys and authorized_keys, many thanks to Vladislav Grishenko.
+  This also replaces curve25519 with a TweetNaCl implementation that reduces code size.
+
+- Add chacha20-poly1305 authenticated cipher. This will perform faster than AES
+  on many platforms. Thanks to Vladislav Grishenko
+
+- Support using rsa-sha2 signatures. No changes are needed to hostkeys/authorized_keys
+  entries, existing RSA keys can be used with the new signature format (signatures
+  are ephemeral within a session). Old ssh-rsa signatures will no longer
+  be supported by OpenSSH in future so upgrading is recommended.
+
+- Use getrandom() call on Linux to ensure sufficient entropy has been gathered at startup.
+  Dropbear now avoids reading from the random source at startup, instead waiting until
+  the first connection. It is possible that some platforms were running without enough 
+  entropy previously, those could potentially block at first boot generating host keys.
+  The dropbear "-R" option is one way to avoid that.
+
+- Upgrade libtomcrypt to 1.18.2 and libtommath to 1.2.0, many thanks to Steffen Jaeckel for
+  updating Dropbear to use the current API. Dropbear's configure script will check 
+  for sufficient system library versions, otherwise using the bundled versions.
+
+- CBC ciphers, 3DES, hmac-sha1-96, and x11 forwarding are now disabled by default.
+  They can be set in localoptions.h if required.
+  Blowfish has been removed.
+
+- Support AES GCM, patch from Vladislav Grishenko. This is disabled by default,
+  Dropbear doesn't currently use hardware accelerated AES.
+
+- Added an API for specifying user public keys as an authorized_keys replacement.
+  See pubkeyapi.h for details, thanks to Fabrizio Bertocci
+
+- Fix idle detection clashing with keepalives, thanks to jcmathews
+
+- Include IP addresses in more early exit messages making it easier for fail2ban
+  processing. Patch from Kevin Darbyshire-Bryant
+
+- scp fix for CVE-2018-20685 where a server could modify name of output files
+
+- SSH_ORIGINAL_COMMAND is set for "dropbear -c" forced command too
+
+- Fix writing key files on systems without hard links, from Matt Robinson
+
+- Compatibility fixes for IRIX from Kazuo Kuroi
+
+- Re-enable printing MOTD by default, was lost moving from options.h. Thanks to zciendor
+
+- Call fsync() is called on parent directory when writing key files to ensure they are flushed
+
+- Fix "make install" for manpages in out-of-tree builds, from Gabor Z. Papp
+
+- Some notes are added in DEVELOPING.md
+
+2019.78 - 27 March 2019
+
+- Fix dbclient regression in 2019.77. After exiting the terminal would be left
+  in a bad state. Reported by Ryan Woodsmall
+  
+2019.77 - 23 March 2019
+
+- Fix server -R option with ECDSA - only advertise one key size which will be accepted.
+  Reported by Peter Krefting, 2018.76 regression.
+
+- Fix server regression in 2018.76 where multiple client -R forwards were all forwarded 
+  to the first destination. Reported by Iddo Samet.
+
+- Make failure delay more consistent to avoid revealing valid usernames, set server password 
+  limit of 100 characters. Problem reported by usd responsible disclosure team
+
+- Change handling of failed authentication to avoid disclosing valid usernames,
+  CVE-2018-15599. 
+
+- Fix dbclient to reliably return the exit code from the remote server.
+  Reported by W. Mike Petullo
+
+- Fix export of 521-bit ECDSA keys, from Christian Hohnstädt
+
+- Add -o Port=xxx option to work with sshfs, from xcko
+
+- Merged fuzzing code, see FUZZER-NOTES.md
+
+- Add a DROPBEAR_SVR_MULTIUSER=0 compile option to run on 
+  single-user Linux kernels (CONFIG_MULTIUSER disabled). From Patrick Stewart
+
+- Increase allowed username to 100 characters, reported by W. Mike Petullo
+
+- Update config.sub and config.guess, should now work with RISC-V
+
+- Cygwin compile fix from karel-m
+
+- Don't require GNU sed (accidentally in 2018.76), reported by Samuel Hsu
+
+- Fix for IRIX and writev(), reported by Kazuo Kuroi
+
+- Other fixes and cleanups from François Perrad, Andre McCurdy, Konstantin Demin,
+  Michael Jones, Pawel Rapkiewicz
+
+
 2018.76 - 27 February 2018
 
 > > > Configuration/compatibility changes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEVELOPING.md	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,75 @@
+# Developer Notes
+
+## Building
+
+See [INSTALL](INSTALL) for build instructions. 
+[SMALL](SMALL) has hints for building smaller binaries, also see comments
+in default_options.h.
+
+## Debug printing
+
+Set `#define DEBUG_TRACE 1` in localoptions.h to enable a `-v` option
+for dropbear and dbclient. That prints various details of the session. For
+development running `dropbear -F -E` is useful to run in the foreground. You
+can set `#define DEBUG_NOFORK 1` to make dropbear a one-shot server, easy to 
+run under a debugger.
+
+## Random sources
+
+Most cryptography requires a good random entropy source, both to generate secret
+keys and in the course of a session. Dropbear uses the Linux kernel's
+`getrandom()` syscall to ensure that the system RNG has been initialised before
+using it. On some systems there is insufficient entropy gathered during early
+boot - generating hostkeys then will block for some amount of time. 
+Dropbear has a `-R` option to generate hostkeys upon the first connection 
+as required - that will allow the system more time to gather entropy.
+
+## Algorithms
+
+Default algorithm lists are specified in [common-algo.c](common-algo.c).
+They are in priority order, the client's first matching choice is used
+(see rfc4253). 
+Dropbear client has `-c` and `-m` arguments to choose which are enabled at
+runtime (doesn't work for server as of June 2020).
+
+Enabling/disabling algorithms is done in [localoptions.h](localoptions.h),
+see [default_options.h](default_options.h).
+
+## Style
+
+Source code is indented with tabs, width set to 4 (though width shouldn't
+matter much). Braces are on the same line as functions/loops/if - try
+to keep consistency with existing code.
+
+All `if` statements should have braces, no exceptions.
+
+Avoid using pointer arithmetic, instead the functions in
+[buffer.h](buffer.h) should be used.
+
+Some Dropbear platforms have old compilers.
+Variable declarations must be at the top of a scope and
+comments must be `/* */` rather than `//`.
+
+Pointer variables should be initialised to NULL - it can reduce the
+severity of bugs.
+
+## Third party code
+
+Libtomcrypt and libtommath are periodically synced from upstream, so
+avoid making changes to that code which will need to be maintained.
+Improvements can be sent upstream to the libtom project.
+
+## Non-root user
+
+Dropbear server will run fine as a non-root user, allowing logins only for 
+that user. Password authentication probably won't work (can't read shadow 
+passwords). You will need to create hostkeys that are readable.
+
+## Connection setup 
+
+Dropbear implements first_kex_packet_follows to reduce 
+handshake latency (rfc 4253 7.1). Some less common implementations don't 
+handle that, it can be a cause of problems connecting. Note also that
+Dropbear may send several ssh packets within a single TCP packet - it's just a 
+stream.
+
--- a/FUZZER-NOTES.md	Thu Mar 21 23:28:59 2019 +0800
+++ b/FUZZER-NOTES.md	Fri Jun 26 21:07:34 2020 +0800
@@ -72,3 +72,6 @@
 
 - [fuzzer-kexecdh](fuzzer-kexecdh.c) - test Elliptic Curve Diffie-Hellman key exchange like fuzzer-kexdh.
   This is testing libtommath ECC routines.
+
+- [fuzzer-kexcurve25519](fuzzer-kexcurve25519.c) - test Curve25519 Elliptic Curve Diffie-Hellman key exchange
+  like fuzzer-kexecdh. This is testing `dropbear_curve25519_scalarmult()` and other libtommath routines.
--- a/INSTALL	Thu Mar 21 23:28:59 2019 +0800
+++ b/INSTALL	Fri Jun 26 21:07:34 2020 +0800
@@ -28,6 +28,8 @@
 recompile after changing the PROGRAMS list, you *MUST* "make clean" before
 recompiling - bad things will happen otherwise)
 
+DEVELOPING.md has some notes on other developer topics, including debugging.
+
 See MULTI for instructions on making all-in-one binaries.
 
 If you want to compile statically use ./configure --enable-static
@@ -56,7 +58,7 @@
 uClibc toolchain compiler (ie export CC=i386-uclibc-gcc or whatever).
 You can use "make STATIC=1" to make statically linked binaries, and it is
 advisable to strip the binaries too. If you're looking to make a small binary,
-you should remove unneeded ciphers and MD5, by editing options.h
+you should remove unneeded ciphers and MD5, by editing localoptions.h
 
 It is possible to compile zlib in, by copying zlib.h and zconf.h into a
 subdirectory (ie zlibincludes), and 
--- a/LICENSE	Thu Mar 21 23:28:59 2019 +0800
+++ b/LICENSE	Fri Jun 26 21:07:34 2020 +0800
@@ -8,7 +8,7 @@
 Portions of the client-mode work are (c) 2004 Mihnea Stoenescu, under the
 same license:
 
-Copyright (c) 2002-2015 Matt Johnston
+Copyright (c) 2002-2020 Matt Johnston
 Portions copyright (c) 2004 Mihnea Stoenescu
 All rights reserved.
 
@@ -32,7 +32,8 @@
 
 =====
 
-LibTomCrypt and LibTomMath are written by Tom St Denis, and are Public Domain.
+LibTomCrypt and LibTomMath are written by Tom St Denis and others, see
+libtomcrypt/LICENSE and libtommath/LICENSE.
 
 =====
 
@@ -90,52 +91,24 @@
 
 =====
 
-curve25519-donna:
+curve25519.c:
+
+Modified TweetNaCl version 20140427, a self-contained public-domain C library.
+https://tweetnacl.cr.yp.to/
 
-/* Copyright 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * curve25519-donna: Curve25519 elliptic curve, public key function
- *
- * http://code.google.com/p/curve25519-donna/
- *
- * Adam Langley <[email protected]>
- *
- * Derived from public domain C code by Daniel J. Bernstein <[email protected]>
- *
- * More information about curve25519 can be found here
- *   http://cr.yp.to/ecdh.html
- *
- * djb's sample implementation of curve25519 is written in a special assembly
- * language called qhasm and uses the floating point registers.
- *
- * This is, almost, a clean room reimplementation from the curve25519 paper. It
- * uses many of the tricks described therein. Only the crecip function is taken
- * from the sample implementation.
- */
+Contributors (alphabetical order)
+Daniel J. Bernstein, University of Illinois at Chicago and Technische
+Universiteit Eindhoven
+Bernard van Gastel, Radboud Universiteit Nijmegen
+Wesley Janssen, Radboud Universiteit Nijmegen
+Tanja Lange, Technische Universiteit Eindhoven
+Peter Schwabe, Radboud Universiteit Nijmegen
+Sjaak Smetsers, Radboud Universiteit Nijmegen
+
+Acknowledgments
+This work was supported by the U.S. National Science Foundation under grant
+1018836. "Any opinions, findings, and conclusions or recommendations expressed
+in this material are those of the author(s) and do not necessarily reflect the
+views of the National Science Foundation."
+This work was supported by the Netherlands Organisation for Scientific
+Research (NWO) under grant 639.073.005 and Veni 2013 project 13114.
--- a/Makefile.in	Thu Mar 21 23:28:59 2019 +0800
+++ b/Makefile.in	Fri Jun 26 21:07:34 2020 +0800
@@ -36,8 +36,9 @@
 		queue.o \
 		atomicio.o compat.o fake-rfc2553.o \
 		ltc_prng.o ecc.o ecdsa.o crypto_desc.o \
+		curve25519.o ed25519.o \
 		dbmalloc.o \
-		gensignkey.o gendss.o genrsa.o
+		gensignkey.o gendss.o genrsa.o gened25519.o
 
 SVROBJS=svr-kex.o svr-auth.o sshpty.o \
 		svr-authpasswd.o svr-authpubkey.o svr-authpubkeyoptions.o svr-session.o svr-service.o \
@@ -52,7 +53,7 @@
 CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \
 			common-channel.o common-chansession.o termcodes.o loginrec.o \
 			tcp-accept.o listener.o process-packet.o dh_groups.o \
-			common-runopts.o circbuffer.o curve25519-donna.o list.o netio.o
+			common-runopts.o circbuffer.o list.o netio.o chachapoly.o gcm.o
 
 KEYOBJS=dropbearkey.o
 
@@ -80,6 +81,15 @@
 	scpobjs=$(SCPOBJS)
 endif
 
+ifeq (@DROPBEAR_PLUGIN@, 1)
+    # rdynamic makes all the global symbols of dropbear available to all the loaded shared libraries
+    # this allow a plugin to reuse existing crypto/utilities like base64_decode/base64_encode without
+    # the need to rewrite them.
+    PLUGIN_LIBS=-ldl -rdynamic
+else
+    PLUGIN_LIBS=
+endif
+
 VPATH=@srcdir@
 srcdir=@srcdir@
 
@@ -165,7 +175,7 @@
 	-rm -f $(DESTDIR)$(bindir)/$*$(EXEEXT) 
 	-ln -s $(bindir)/dropbearmulti$(EXEEXT) $(DESTDIR)$(bindir)/$*$(EXEEXT) 
 	$(INSTALL) -d $(DESTDIR)$(mandir)/man1
-	if test -e $*.1; then $(INSTALL) -m 644 $*.1 $(DESTDIR)$(mandir)/man1/$*.1; fi
+	if test -e $(srcdir)/$*.1; then $(INSTALL) -m 644 $(srcdir)/$*.1 $(DESTDIR)$(mandir)/man1/$*.1; fi
 
 # dropbear should go in sbin, so it needs a separate rule
 inst_dropbear: dropbear
@@ -178,7 +188,7 @@
 	$(INSTALL) -d $(DESTDIR)$(bindir)
 	$(INSTALL) $*$(EXEEXT) $(DESTDIR)$(bindir)
 	$(INSTALL) -d $(DESTDIR)$(mandir)/man1
-	if test -e $*.1; then $(INSTALL) -m 644 $*.1 $(DESTDIR)$(mandir)/man1/$*.1; fi
+	if test -e $(srcdir)/$*.1; then $(INSTALL) -m 644 $(srcdir)/$*.1 $(DESTDIR)$(mandir)/man1/$*.1; fi
 
 inst_dropbearmulti: $(addprefix insmulti, $(PROGRAMS)) 
 
@@ -189,7 +199,7 @@
 dropbearconvert: $(dropbearconvertobjs)
 
 dropbear: $(HEADERS) $(LIBTOM_DEPS) Makefile
-	$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@
+	$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS) @CRYPTLIB@ $(PLUGIN_LIBS)
 
 dbclient: $(HEADERS) $(LIBTOM_DEPS) Makefile
 	$(CC) $(LDFLAGS) -o $@$(EXEEXT) $($@objs) $(LIBTOM_LIBS) $(LIBS)
@@ -226,7 +236,7 @@
 $(STATIC_LTM): $(OPTION_HEADERS)
 	$(MAKE) -C libtommath
 
-.PHONY : clean sizes thisclean distclean tidy ltc-clean ltm-clean
+.PHONY : clean sizes thisclean distclean tidy ltc-clean ltm-clean lint
 
 ltc-clean:
 	$(MAKE) -C libtomcrypt clean
@@ -252,10 +262,13 @@
 tidy:
 	-rm -f *~ *.gcov */*~
 
+lint:
+	cd $(srcdir); ./dropbear_lint.sh
+
 ## Fuzzing targets
 
 # list of fuzz targets
-FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths fuzzer-kexdh fuzzer-kexecdh
+FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519
 
 FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS))
 
@@ -269,27 +282,32 @@
 # exclude svr-main.o to avoid duplicate main
 svrfuzzobjs=$(subst svr-main.o, ,$(dropbearobjs))
 
+fuzz-harness.o: $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs) fuzz-common.o
+
 # build all the fuzzers. This will require fail to link unless built with
 # make fuzz-targets FUZZLIB=-lFuzzer.a 
 # or similar - the library provides main().
 fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS)
 
-fuzzer-preauth: fuzzer-preauth.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
+fuzzer-preauth: fuzzer-preauth.o fuzz-harness.o
 	$(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
 
-fuzzer-preauth_nomaths: fuzzer-preauth_nomaths.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
+fuzzer-preauth_nomaths: fuzzer-preauth_nomaths.o fuzz-harness.o
+	$(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
+
+fuzzer-pubkey: fuzzer-pubkey.o fuzz-harness.o
 	$(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
 
-fuzzer-pubkey: fuzzer-pubkey.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
+fuzzer-verify: fuzzer-verify.o fuzz-harness.o
 	$(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
 
-fuzzer-verify: fuzzer-verify.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
+fuzzer-kexdh: fuzzer-kexdh.o fuzz-harness.o
 	$(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
 
-fuzzer-kexdh: fuzzer-kexdh.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
+fuzzer-kexecdh: fuzzer-kexecdh.o fuzz-harness.o
 	$(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
 
-fuzzer-kexecdh: fuzzer-kexecdh.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
+fuzzer-kexcurve25519: fuzzer-kexcurve25519.o fuzz-harness.o
 	$(CXX) $(CXXFLAGS) [email protected] $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
 
 fuzzer-%.options: Makefile
@@ -302,11 +320,14 @@
 	dropbearkey -t rsa -f keyr
 	dropbearkey -t dss -f keyd
 	dropbearkey -t ecdsa -size 256 -f keye
+	dropbearkey -t ed25519 -f keyed25519
 	echo > hostkeys.c
 	/usr/bin/xxd -i -a keyr >> hostkeys.c
 	/usr/bin/xxd -i -a keye >> hostkeys.c
 	/usr/bin/xxd -i -a keyd >> hostkeys.c
+	/usr/bin/xxd -i -a keyed25519 >> hostkeys.c
 
 # to make coverity happy?
 test:
 	true
+
--- a/README	Thu Mar 21 23:28:59 2019 +0800
+++ b/README	Fri Jun 26 21:07:34 2020 +0800
@@ -55,6 +55,7 @@
 ./dropbearkey -t rsa -f dropbear_rsa_host_key
 ./dropbearkey -t dss -f dropbear_dss_host_key
 ./dropbearkey -t ecdsa -f dropbear_ecdsa_host_key
+./dropbearkey -t ed25519 -f dropbear_ed25519_host_key
 
 or alternatively convert OpenSSH keys to Dropbear:
 ./dropbearconvert openssh dropbear /etc/ssh/ssh_host_dsa_key dropbear_dss_host_key
--- a/agentfwd.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/agentfwd.h	Fri Jun 26 21:07:34 2020 +0800
@@ -32,6 +32,9 @@
 
 #if DROPBEAR_CLI_AGENTFWD
 
+/* From OpenSSH authfd.h */
+#define SSH_AGENT_RSA_SHA2_256          0x02
+
 /* An agent reply can be reasonably large, as it can
  * contain a list of all public keys held by the agent.
  * 10000 is arbitrary */
@@ -40,7 +43,7 @@
 /* client functions */
 void cli_load_agent_keys(m_list * ret_list);
 void agent_buf_sign(buffer *sigblob, sign_key *key, 
-	const buffer *data_buf);
+		const buffer *data_buf, enum signature_type type);
 void cli_setup_agent(const struct Channel *channel);
 
 #ifdef __hpux
--- a/algo.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/algo.h	Fri Jun 26 21:07:34 2020 +0800
@@ -47,7 +47,7 @@
 
 /* lists mapping ssh types of algorithms to internal values */
 extern algo_type sshkex[];
-extern algo_type sshhostkey[];
+extern algo_type sigalgs[];
 extern algo_type sshciphers[];
 extern algo_type sshhashes[];
 extern algo_type ssh_compress[];
@@ -72,6 +72,14 @@
 			unsigned long len, void *cipher_state);
 	int (*decrypt)(const unsigned char *ct, unsigned char *pt, 
 			unsigned long len, void *cipher_state);
+	int (*aead_crypt)(unsigned int seq,
+			const unsigned char *in, unsigned char *out,
+			unsigned long len, unsigned long taglen,
+			void *cipher_state, int direction);
+	int (*aead_getlength)(unsigned int seq,
+			const unsigned char *in, unsigned int *outlen,
+			unsigned long len, void *cipher_state);
+	const struct dropbear_hash *aead_mac;
 };
 
 struct dropbear_hash {
@@ -112,21 +120,17 @@
 	const struct ltc_hash_descriptor *hash_desc;
 };
 
-int have_algo(const char* algo, size_t algolen, const algo_type algos[]);
+/* Includes all algorithms is useall is set */
+void buf_put_algolist_all(buffer * buf, const algo_type localalgos[], int useall);
+/* Includes "usable" algorithms */
 void buf_put_algolist(buffer * buf, const algo_type localalgos[]);
 
-enum kexguess2_used {
-	KEXGUESS2_LOOK,
-	KEXGUESS2_NO,
-	KEXGUESS2_YES,
-};
+#define KEXGUESS2_ALGO_NAME "[email protected]"
 
-#define KEXGUESS2_ALGO_NAME "[email protected]"
-#define KEXGUESS2_ALGO_ID 99
-
-
+int buf_has_algo(buffer *buf, const char *algo);
+algo_type * first_usable_algo(algo_type algos[]);
 algo_type * buf_match_algo(buffer* buf, algo_type localalgos[],
-		enum kexguess2_used *kexguess2, int *goodguess);
+		int kexguess2, int *goodguess);
 
 #if DROPBEAR_USER_ALGO_LIST
 int check_user_algos(const char* user_algo_list, algo_type * algos, 
--- a/bignum.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/bignum.c	Fri Jun 26 21:07:34 2020 +0800
@@ -86,7 +86,7 @@
 
 void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) {
 
-	if (mp_read_unsigned_bin(mp, (unsigned char*)bytes, len) != MP_OKAY) {
+	if (mp_from_ubin(mp, (unsigned char*)bytes, len) != MP_OKAY) {
 		dropbear_exit("Mem alloc error");
 	}
 }
--- a/buffer.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/buffer.c	Fri Jun 26 21:07:34 2020 +0800
@@ -228,19 +228,37 @@
 }
 
 /* Return a string as a newly allocated buffer */
-buffer * buf_getstringbuf(buffer *buf) {
+static buffer * buf_getstringbuf_int(buffer *buf, int incllen) {
 	buffer *ret = NULL;
 	unsigned int len = buf_getint(buf);
+	int extra = 0;
 	if (len > MAX_STRING_LEN) {
 		dropbear_exit("String too long");
 	}
-	ret = buf_new(len);
+	if (incllen) {
+		extra = 4;
+	}
+	ret = buf_new(len+extra);
+	if (incllen) {
+		buf_putint(ret, len);
+	}
 	memcpy(buf_getwriteptr(ret, len), buf_getptr(buf, len), len);
 	buf_incrpos(buf, len);
 	buf_incrlen(ret, len);
+	buf_setpos(ret, 0);
 	return ret;
 }
 
+/* Return a string as a newly allocated buffer */
+buffer * buf_getstringbuf(buffer *buf) {
+	return buf_getstringbuf_int(buf, 0);
+}
+
+/* Returns a string in a new buffer, including the length */
+buffer * buf_getbuf(buffer *buf) {
+	return buf_getstringbuf_int(buf, 1);
+}
+
 /* Just increment the buffer position the same as if we'd used buf_getstring,
  * but don't bother copying/malloc()ing for it */
 void buf_eatstring(buffer *buf) {
@@ -289,18 +307,18 @@
 /* for our purposes we only need positive (or 0) numbers, so will
  * fail if we get negative numbers */
 void buf_putmpint(buffer* buf, mp_int * mp) {
-
+	size_t written;
 	unsigned int len, pad = 0;
 	TRACE2(("enter buf_putmpint"))
 
 	dropbear_assert(mp != NULL);
 
-	if (SIGN(mp) == MP_NEG) {
+	if (mp_isneg(mp)) {
 		dropbear_exit("negative bignum");
 	}
 
 	/* zero check */
-	if (USED(mp) == 1 && DIGIT(mp, 0) == 0) {
+	if (mp_iszero(mp)) {
 		len = 0;
 	} else {
 		/* SSH spec requires padding for mpints with the MSB set, this code
@@ -321,10 +339,10 @@
 		if (pad) {
 			buf_putbyte(buf, 0x00);
 		}
-		if (mp_to_unsigned_bin(mp, buf_getwriteptr(buf, len-pad)) != MP_OKAY) {
+		if (mp_to_ubin(mp, buf_getwriteptr(buf, len-pad), len-pad, &written) != MP_OKAY) {
 			dropbear_exit("mpint error");
 		}
-		buf_incrwritepos(buf, len-pad);
+		buf_incrwritepos(buf, written);
 	}
 
 	TRACE2(("leave buf_putmpint"))
@@ -352,7 +370,7 @@
 		return DROPBEAR_FAILURE;
 	}
 
-	if (mp_read_unsigned_bin(mp, buf_getptr(buf, len), len) != MP_OKAY) {
+	if (mp_from_ubin(mp, buf_getptr(buf, len), len) != MP_OKAY) {
 		return DROPBEAR_FAILURE;
 	}
 
--- a/buffer.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/buffer.h	Fri Jun 26 21:07:34 2020 +0800
@@ -58,6 +58,7 @@
 unsigned char* buf_getwriteptr(const buffer* buf, unsigned int len);
 char* buf_getstring(buffer* buf, unsigned int *retlen);
 buffer * buf_getstringbuf(buffer *buf);
+buffer * buf_getbuf(buffer *buf);
 void buf_eatstring(buffer *buf);
 void buf_putint(buffer* buf, unsigned int val);
 void buf_putstring(buffer* buf, const char* str, unsigned int len);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chachapoly.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,148 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * Copyright (c) 2020 by Vladislav Grishenko
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "algo.h"
+#include "dbutil.h"
+#include "chachapoly.h"
+
+#if DROPBEAR_CHACHA20POLY1305
+
+#define CHACHA20_KEY_LEN 32
+#define CHACHA20_BLOCKSIZE 8
+#define POLY1305_KEY_LEN 32
+#define POLY1305_TAG_LEN 16
+
+static const struct ltc_cipher_descriptor dummy = {.name = NULL};
+
+static const struct dropbear_hash dropbear_chachapoly_mac =
+	{NULL, POLY1305_KEY_LEN, POLY1305_TAG_LEN};
+
+const struct dropbear_cipher dropbear_chachapoly =
+	{&dummy, CHACHA20_KEY_LEN*2, CHACHA20_BLOCKSIZE};
+
+static int dropbear_chachapoly_start(int UNUSED(cipher), const unsigned char* UNUSED(IV),
+			const unsigned char *key, int keylen,
+			int UNUSED(num_rounds), dropbear_chachapoly_state *state) {
+	int err;
+
+	TRACE2(("enter dropbear_chachapoly_start"))
+
+	if (keylen != CHACHA20_KEY_LEN*2) {
+		return CRYPT_ERROR;
+	}
+
+	if ((err = chacha_setup(&state->chacha, key,
+				CHACHA20_KEY_LEN, 20)) != CRYPT_OK) {
+		return err;
+	}
+
+	if ((err = chacha_setup(&state->header, key + CHACHA20_KEY_LEN,
+				CHACHA20_KEY_LEN, 20) != CRYPT_OK)) {
+		return err;
+	}
+
+	TRACE2(("leave dropbear_chachapoly_start"))
+	return CRYPT_OK;
+}
+
+static int dropbear_chachapoly_crypt(unsigned int seq,
+			const unsigned char *in, unsigned char *out,
+			unsigned long len, unsigned long taglen,
+			dropbear_chachapoly_state *state, int direction) {
+	poly1305_state poly;
+	unsigned char seqbuf[8], key[POLY1305_KEY_LEN], tag[POLY1305_TAG_LEN];
+	int err;
+
+	TRACE2(("enter dropbear_chachapoly_crypt"))
+
+	if (len < 4 || taglen != POLY1305_TAG_LEN) {
+		return CRYPT_ERROR;
+	}
+
+	STORE64H((uint64_t)seq, seqbuf);
+	chacha_ivctr64(&state->chacha, seqbuf, sizeof(seqbuf), 0);
+	if ((err = chacha_keystream(&state->chacha, key, sizeof(key))) != CRYPT_OK) {
+		return err;
+	}
+
+	poly1305_init(&poly, key, sizeof(key));
+	if (direction == LTC_DECRYPT) {
+		poly1305_process(&poly, in, len);
+		poly1305_done(&poly, tag, &taglen);
+		if (constant_time_memcmp(in + len, tag, taglen) != 0) {
+			return CRYPT_ERROR;
+		}
+	}
+
+	chacha_ivctr64(&state->header, seqbuf, sizeof(seqbuf), 0);
+	if ((err = chacha_crypt(&state->header, in, 4, out)) != CRYPT_OK) {
+		return err;
+	}
+
+	chacha_ivctr64(&state->chacha, seqbuf, sizeof(seqbuf), 1);
+	if ((err = chacha_crypt(&state->chacha, in + 4, len - 4, out + 4)) != CRYPT_OK) {
+		return err;
+	}
+
+	if (direction == LTC_ENCRYPT) {
+		poly1305_process(&poly, out, len);
+		poly1305_done(&poly, out + len, &taglen);
+	}
+
+	TRACE2(("leave dropbear_chachapoly_crypt"))
+	return CRYPT_OK;
+}
+
+static int dropbear_chachapoly_getlength(unsigned int seq,
+			const unsigned char *in, unsigned int *outlen,
+			unsigned long len, dropbear_chachapoly_state *state) {
+	unsigned char seqbuf[8], buf[4];
+	int err;
+
+	TRACE2(("enter dropbear_chachapoly_getlength"))
+
+	if (len < sizeof(buf)) {
+		return CRYPT_ERROR;
+	}
+
+	STORE64H((uint64_t)seq, seqbuf);
+	chacha_ivctr64(&state->header, seqbuf, sizeof(seqbuf), 0);
+	if ((err = chacha_crypt(&state->header, in, sizeof(buf), buf)) != CRYPT_OK) {
+		return err;
+	}
+
+	LOAD32H(*outlen, buf);
+
+	TRACE2(("leave dropbear_chachapoly_getlength"))
+	return CRYPT_OK;
+}
+
+const struct dropbear_cipher_mode dropbear_mode_chachapoly =
+	{(void *)dropbear_chachapoly_start, NULL, NULL,
+	 (void *)dropbear_chachapoly_crypt,
+	 (void *)dropbear_chachapoly_getlength, &dropbear_chachapoly_mac};
+
+#endif /* DROPBEAR_CHACHA20POLY1305 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chachapoly.h	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,44 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * Copyright (c) 2020 by Vladislav Grishenko
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef DROPBEAR_DROPBEAR_CHACHAPOLY_H_
+#define DROPBEAR_DROPBEAR_CHACHAPOLY_H_
+
+#include "includes.h"
+#include "algo.h"
+
+#if DROPBEAR_CHACHA20POLY1305
+
+typedef struct {
+	chacha_state chacha;
+	chacha_state header;
+} dropbear_chachapoly_state;
+
+extern const struct dropbear_cipher dropbear_chachapoly;
+extern const struct dropbear_cipher_mode dropbear_mode_chachapoly;
+
+#endif /* DROPBEAR_CHACHA20POLY1305 */
+
+#endif /* DROPBEAR_DROPBEAR_CHACHAPOLY_H_ */
--- a/chansession.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/chansession.h	Fri Jun 26 21:07:34 2020 +0800
@@ -41,6 +41,9 @@
 
 	char * cmd; /* command to exec */
 	pid_t pid; /* child process pid */
+	/* command that was sent by the client, if authorized_keys command= or
+	dropbear -c was used */
+	char *original_command;
 
 	/* pty details */
 	int master; /* the master terminal fd*/
@@ -72,10 +75,6 @@
 	char * agentfile;
 	char * agentdir;
 #endif
-
-#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT
-	char *original_command;
-#endif
 };
 
 struct ChildPid {
--- a/cli-agentfwd.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/cli-agentfwd.c	Fri Jun 26 21:07:34 2020 +0800
@@ -255,11 +255,12 @@
 }
 
 void agent_buf_sign(buffer *sigblob, sign_key *key, 
-		const buffer *data_buf) {
+		const buffer *data_buf, enum signature_type sigtype) {
 	buffer *request_data = NULL;
 	buffer *response = NULL;
 	unsigned int siglen;
 	int packet_type;
+	int flags = 0;
 	
 	/* Request format
 	byte			SSH2_AGENTC_SIGN_REQUEST
@@ -271,7 +272,12 @@
 	buf_put_pub_key(request_data, key, key->type);
 	
 	buf_putbufstring(request_data, data_buf);
-	buf_putint(request_data, 0);
+#if DROPBEAR_RSA_SHA256
+	if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) {
+		flags |= SSH_AGENT_RSA_SHA2_256;
+	}
+#endif
+	buf_putint(request_data, flags);
 	
 	response = agent_request(SSH2_AGENTC_SIGN_REQUEST, request_data);
 	
--- a/cli-authpubkey.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/cli-authpubkey.c	Fri Jun 26 21:07:34 2020 +0800
@@ -33,7 +33,7 @@
 #include "agentfwd.h"
 
 #if DROPBEAR_CLI_PUBKEY_AUTH
-static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign);
+static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign);
 
 /* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request.
  * We use it to remove the key we tried from the list */
@@ -59,13 +59,15 @@
 	char* algotype = NULL;
 	unsigned int algolen;
 	enum signkey_type keytype;
+	enum signature_type sigtype;
 	unsigned int remotelen;
 
 	TRACE(("enter recv_msg_userauth_pk_ok"))
 
 	algotype = buf_getstring(ses.payload, &algolen);
-	keytype = signkey_type_from_name(algotype, algolen);
-	TRACE(("recv_msg_userauth_pk_ok: type %d", keytype))
+	sigtype = signature_type_from_name(algotype, algolen);
+	keytype = signkey_type_from_signature(sigtype);
+	TRACE(("recv_msg_userauth_pk_ok: type %d", sigtype))
 	m_free(algotype);
 
 	keybuf = buf_new(MAX_PUBKEY_SIZE);
@@ -112,7 +114,7 @@
 		TRACE(("matching key"))
 		/* XXX TODO: if it's an encrypted key, here we ask for their
 		 * password */
-		send_msg_userauth_pubkey((sign_key*)iter->item, keytype, 1);
+		send_msg_userauth_pubkey((sign_key*)iter->item, sigtype, 1);
 	} else {
 		TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part"))
 	}
@@ -120,31 +122,32 @@
 	TRACE(("leave recv_msg_userauth_pk_ok"))
 }
 
-void cli_buf_put_sign(buffer* buf, sign_key *key, int type, 
+static void cli_buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
 			const buffer *data_buf) {
 #if DROPBEAR_CLI_AGENTFWD
+	// TODO: rsa-sha256 agent
 	if (key->source == SIGNKEY_SOURCE_AGENT) {
 		/* Format the agent signature ourselves, as buf_put_sign would. */
 		buffer *sigblob;
 		sigblob = buf_new(MAX_PUBKEY_SIZE);
-		agent_buf_sign(sigblob, key, data_buf);
+		agent_buf_sign(sigblob, key, data_buf, sigtype);
 		buf_putbufstring(buf, sigblob);
 		buf_free(sigblob);
 	} else 
 #endif /* DROPBEAR_CLI_AGENTFWD */
 	{
-		buf_put_sign(buf, key, type, data_buf);
+		buf_put_sign(buf, key, sigtype, data_buf);
 	}
 }
 
-/* TODO: make it take an agent reference to use as well */
-static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
+static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign) {
 
 	const char *algoname = NULL;
 	unsigned int algolen;
 	buffer* sigbuf = NULL;
+	enum signkey_type keytype = signkey_type_from_signature(sigtype);
 
-	TRACE(("enter send_msg_userauth_pubkey"))
+	TRACE(("enter send_msg_userauth_pubkey sigtype %d", sigtype))
 	CHECKCLEARTOWRITE();
 
 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
@@ -160,10 +163,9 @@
 
 	buf_putbyte(ses.writepayload, realsign);
 
-	algoname = signkey_name_from_type(type, &algolen);
-
+	algoname = signature_name_from_type(sigtype, &algolen);
 	buf_putstring(ses.writepayload, algoname, algolen);
-	buf_put_pub_key(ses.writepayload, key, type);
+	buf_put_pub_key(ses.writepayload, key, keytype);
 
 	if (realsign) {
 		TRACE(("realsign"))
@@ -172,7 +174,7 @@
 		sigbuf = buf_new(4 + ses.session_id->len + ses.writepayload->len);
 		buf_putbufstring(sigbuf, ses.session_id);
 		buf_putbytes(sigbuf, ses.writepayload->data, ses.writepayload->len);
-		cli_buf_put_sign(ses.writepayload, key, type, sigbuf);
+		cli_buf_put_sign(ses.writepayload, key, sigtype, sigbuf);
 		buf_free(sigbuf); /* Nothing confidential in the buffer */
 	}
 
@@ -182,7 +184,7 @@
 
 /* Returns 1 if a key was tried */
 int cli_auth_pubkey() {
-
+	enum signature_type sigtype = DROPBEAR_SIGNATURE_NONE;
 	TRACE(("enter cli_auth_pubkey"))
 
 #if DROPBEAR_CLI_AGENTFWD
@@ -190,13 +192,79 @@
 		/* get the list of available keys from the agent */
 		cli_load_agent_keys(cli_opts.privkeys);
 		cli_opts.agent_keys_loaded = 1;
+		TRACE(("cli_auth_pubkey: agent keys loaded"))
 	}
 #endif
 
+	/* iterate through privkeys to remove ones not allowed in server-sig-algs */
+ 	while (cli_opts.privkeys->first) {
+		sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
+		if (cli_ses.server_sig_algs) {
+#if DROPBEAR_RSA
+			if (key->type == DROPBEAR_SIGNKEY_RSA) {
+#if DROPBEAR_RSA_SHA256
+				if (buf_has_algo(cli_ses.server_sig_algs, SSH_SIGNATURE_RSA_SHA256) 
+						== DROPBEAR_SUCCESS) {
+					sigtype = DROPBEAR_SIGNATURE_RSA_SHA256;
+					TRACE(("server-sig-algs allows rsa sha256"))
+					break;
+				}
+#endif /* DROPBEAR_RSA_SHA256 */
+#if DROPBEAR_RSA_SHA1
+				if (buf_has_algo(cli_ses.server_sig_algs, SSH_SIGNKEY_RSA)
+						== DROPBEAR_SUCCESS) {
+					sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
+					TRACE(("server-sig-algs allows rsa sha1"))
+					break;
+				}
+#endif /* DROPBEAR_RSA_SHA256 */
+			} else
+#endif /* DROPBEAR_RSA */
+			{
+				/* Not RSA */
+				const char *name = NULL;
+				sigtype = signature_type_from_signkey(key->type);
+				name = signature_name_from_type(sigtype, NULL);
+				if (buf_has_algo(cli_ses.server_sig_algs, name)
+						== DROPBEAR_SUCCESS) {
+					TRACE(("server-sig-algs allows %s", name))
+					break;
+				}
+			}
+
+			/* No match, skip this key */
+			TRACE(("server-sig-algs no match keytype %d, skipping", key->type))
+			key = list_remove(cli_opts.privkeys->first);
+			sign_key_free(key); 
+			continue;
+		} else {
+			/* Server didn't provide a server-sig-algs list, we'll 
+			   assume all except rsa-sha256 are OK. */
+#if DROPBEAR_RSA
+			if (key->type == DROPBEAR_SIGNKEY_RSA) {
+#if DROPBEAR_RSA_SHA1
+				sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
+				TRACE(("no server-sig-algs, using rsa sha1"))
+				break;
+#else
+				/* only support rsa-sha256, skip this key */
+				TRACE(("no server-sig-algs, skipping rsa sha256"))
+				key = list_remove(cli_opts.privkeys->first);
+				sign_key_free(key); 
+				continue;
+#endif
+			} /* key->type == DROPBEAR_SIGNKEY_RSA */
+#endif /* DROPBEAR_RSA */
+			sigtype = signature_type_from_signkey(key->type);
+			TRACE(("no server-sig-algs, using key"))
+			break;
+		}
+	}
+
 	if (cli_opts.privkeys->first) {
 		sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
 		/* Send a trial request */
-		send_msg_userauth_pubkey(key, key->type, 0);
+		send_msg_userauth_pubkey(key, sigtype, 0);
 		cli_ses.lastprivkey = key;
 		TRACE(("leave cli_auth_pubkey-success"))
 		return 1;
--- a/cli-chansession.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/cli-chansession.c	Fri Jun 26 21:07:34 2020 +0800
@@ -35,7 +35,7 @@
 #include "chansession.h"
 #include "agentfwd.h"
 
-static void cli_cleanupchansess(const struct Channel *channel);
+static void cli_closechansess(const struct Channel *channel);
 static int cli_initchansess(struct Channel *channel);
 static void cli_chansessreq(struct Channel *channel);
 static void send_chansess_pty_req(const struct Channel *channel);
@@ -51,8 +51,8 @@
 	cli_initchansess, /* inithandler */
 	NULL, /* checkclosehandler */
 	cli_chansessreq, /* reqhandler */
-	NULL, /* closehandler */
-	cli_cleanupchansess, /* cleanup */
+	cli_closechansess, /* closehandler */
+	NULL, /* cleanup */
 };
 
 static void cli_chansessreq(struct Channel *channel) {
@@ -84,7 +84,7 @@
 	
 
 /* If the main session goes, we close it up */
-static void cli_cleanupchansess(const struct Channel *UNUSED(channel)) {
+static void cli_closechansess(const struct Channel *UNUSED(channel)) {
 	cli_tty_cleanup(); /* Restore tty modes etc */
 
 	/* This channel hasn't gone yet, so we have > 1 */
@@ -388,8 +388,8 @@
 	cli_init_netcat, /* inithandler */
 	NULL,
 	NULL,
+	cli_closechansess,
 	NULL,
-	cli_cleanupchansess
 };
 
 void cli_send_netcat_request() {
--- a/cli-kex.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/cli-kex.c	Fri Jun 26 21:07:34 2020 +0800
@@ -81,7 +81,7 @@
 				}
 				cli_ses.curve25519_param = gen_kexcurve25519_param();
 			}
-			buf_putstring(ses.writepayload, (const char*)cli_ses.curve25519_param->pub, CURVE25519_LEN);
+			buf_putstring(ses.writepayload, cli_ses.curve25519_param->pub, CURVE25519_LEN);
 			break;
 #endif
 	}
@@ -94,7 +94,7 @@
 void recv_msg_kexdh_reply() {
 
 	sign_key *hostkey = NULL;
-	unsigned int type, keybloblen;
+	unsigned int keytype, keybloblen;
 	unsigned char* keyblob = NULL;
 
 	TRACE(("enter recv_msg_kexdh_reply"))
@@ -102,8 +102,8 @@
 	if (cli_ses.kex_state != KEXDH_INIT_SENT) {
 		dropbear_exit("Received out-of-order kexdhreply");
 	}
-	type = ses.newkeys->algo_hostkey;
-	TRACE(("type is %d", type))
+	keytype = ses.newkeys->algo_hostkey;
+	TRACE(("keytype is %d", keytype))
 
 	hostkey = new_sign_key();
 	keybloblen = buf_getint(ses.payload);
@@ -114,7 +114,7 @@
 		checkhostkey(keyblob, keybloblen);
 	}
 
-	if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) {
+	if (buf_get_pub_key(ses.payload, hostkey, &keytype) != DROPBEAR_SUCCESS) {
 		TRACE(("failed getting pubkey"))
 		dropbear_exit("Bad KEX packet");
 	}
@@ -155,10 +155,12 @@
 #endif
 	}
 
+#if DROPBEAR_NORMAL_DH
 	if (cli_ses.dh_param) {
 		free_kexdh_param(cli_ses.dh_param);
 		cli_ses.dh_param = NULL;
 	}
+#endif
 #if DROPBEAR_ECDH
 	if (cli_ses.ecdh_param) {
 		free_kexecdh_param(cli_ses.ecdh_param);
@@ -173,7 +175,8 @@
 #endif
 
 	cli_ses.param_kex_algo = NULL;
-	if (buf_verify(ses.payload, hostkey, ses.hash) != DROPBEAR_SUCCESS) {
+	if (buf_verify(ses.payload, hostkey, ses.newkeys->algo_signature, 
+			ses.hash) != DROPBEAR_SUCCESS) {
 		dropbear_exit("Bad hostkey signature");
 	}
 
@@ -410,3 +413,38 @@
 	}
 	m_free(fingerprint);
 }
+
+void recv_msg_ext_info(void) {
+	/* This message is not client-specific in the protocol but Dropbear only handles
+	a server-sent message at present. */
+	unsigned int num_ext;
+	unsigned int i;
+
+	TRACE(("enter recv_msg_ext_info"))
+
+	/* Must be after the first SSH_MSG_NEWKEYS */
+	TRACE(("last %d, donefirst %d, donescond %d", ses.lastpacket, ses.kexstate.donefirstkex, ses.kexstate.donesecondkex))
+	if (!(ses.lastpacket == SSH_MSG_NEWKEYS && !ses.kexstate.donesecondkex)) {
+		TRACE(("leave recv_msg_ext_info: ignoring packet received at the wrong time"))
+		return;
+	}
+
+	num_ext = buf_getint(ses.payload);
+	TRACE(("received SSH_MSG_EXT_INFO with %d items", num_ext))
+
+	for (i = 0; i < num_ext; i++) {
+		unsigned int name_len;
+		char *ext_name = buf_getstring(ses.payload, &name_len);
+		TRACE(("extension %d name '%s'", i, ext_name))
+		if (cli_ses.server_sig_algs == NULL
+				&& name_len == strlen(SSH_SERVER_SIG_ALGS)
+				&& strcmp(ext_name, SSH_SERVER_SIG_ALGS) == 0) {
+			cli_ses.server_sig_algs = buf_getbuf(ses.payload);
+		} else {
+			/* valid extension values could be >MAX_STRING_LEN */
+			buf_eatstring(ses.payload);
+		}
+		m_free(ext_name);
+	}
+	TRACE(("leave recv_msg_ext_info"))
+}
--- a/cli-main.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/cli-main.c	Fri Jun 26 21:07:34 2020 +0800
@@ -106,6 +106,7 @@
 
 	/* Render the formatted exit message */
 	vsnprintf(exitmsg, sizeof(exitmsg), format, param);
+	TRACE(("Exited, cleaning up: %s", exitmsg))
 
 	/* Add the prefix depending on session/auth state */
 	if (!ses.init_done) {
@@ -130,6 +131,12 @@
 		const char* format, va_list param) {
 
 	char printbuf[1024];
+	const char *name;
+
+	name = cli_opts.progname;
+	if (!name) {
+		name = "dbclient";
+	}
 
 	vsnprintf(printbuf, sizeof(printbuf), format, param);
 
@@ -139,7 +146,7 @@
 	}
 #endif
 
-	fprintf(stderr, "%s: %s\n", cli_opts.progname, printbuf);
+	fprintf(stderr, "%s: %s\n", name, printbuf);
 	fflush(stderr);
 }
 
--- a/cli-runopts.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/cli-runopts.c	Fri Jun 26 21:07:34 2020 +0800
@@ -214,7 +214,7 @@
 					cli_opts.always_accept_key = 1;
 					break;
 				case 'p': /* remoteport */
-					next = &cli_opts.remoteport;
+					next = (char**)&cli_opts.remoteport;
 					break;
 #if DROPBEAR_CLI_PUBKEY_AUTH
 				case 'i': /* an identityfile */
@@ -378,6 +378,11 @@
 		}
 	}
 
+#if DROPBEAR_USER_ALGO_LIST
+	/* -c help doesn't need a hostname */
+	parse_ciphers_macs();
+#endif
+
 	/* Done with options/flags; now handle the hostname (which may not
 	 * start with a hyphen) and optional command */
 
@@ -408,10 +413,6 @@
 
 	/* And now a few sanity checks and setup */
 
-#if DROPBEAR_USER_ALGO_LIST
-	parse_ciphers_macs();
-#endif
-
 #if DROPBEAR_CLI_PROXYCMD                                                                                                                                   
 	if (cli_opts.proxycmd) {
 		/* To match the common path of m_freeing it */
--- a/cli-session.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/cli-session.c	Fri Jun 26 21:07:34 2020 +0800
@@ -81,6 +81,7 @@
 	{SSH_MSG_REQUEST_SUCCESS, ignore_recv_response},
 	{SSH_MSG_REQUEST_FAILURE, ignore_recv_response},
 #endif
+	{SSH_MSG_EXT_INFO, recv_msg_ext_info},
 	{0, NULL} /* End */
 };
 
@@ -352,11 +353,13 @@
 	(void)fcntl(cli_ses.stderrcopy, F_SETFL, cli_ses.stderrflags);
 
 	cli_tty_cleanup();
-
+	if (cli_ses.server_sig_algs) {
+		buf_free(cli_ses.server_sig_algs);
+	}
 }
 
 static void cli_finished() {
-	TRACE(("cli_finised()"))
+	TRACE(("cli_finished()"))
 
 	session_cleanup();
 	fprintf(stderr, "Connection to %s@%s:%s closed.\n", cli_opts.username,
--- a/common-algo.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/common-algo.c	Fri Jun 26 21:07:34 2020 +0800
@@ -30,6 +30,9 @@
 #include "dh_groups.h"
 #include "ltc_prng.h"
 #include "ecc.h"
+#include "gcm.h"
+#include "chachapoly.h"
+#include "ssh.h"
 
 /* This file (algo.c) organises the ciphers which can be used, and is used to
  * decide which ciphers/hashes/compression/signing to use during key exchange*/
@@ -61,10 +64,6 @@
 static const struct dropbear_cipher dropbear_aes128 = 
 	{&aes_desc, 16, 16};
 #endif
-#if DROPBEAR_BLOWFISH
-static const struct dropbear_cipher dropbear_blowfish = 
-	{&blowfish_desc, 16, 8};
-#endif
 #if DROPBEAR_TWOFISH256
 static const struct dropbear_cipher dropbear_twofish256 = 
 	{&twofish_desc, 32, 16};
@@ -86,11 +85,11 @@
  * about the symmetric_CBC vs symmetric_CTR cipher_state pointer */
 #if DROPBEAR_ENABLE_CBC_MODE
 const struct dropbear_cipher_mode dropbear_mode_cbc =
-	{(void*)cbc_start, (void*)cbc_encrypt, (void*)cbc_decrypt};
+	{(void*)cbc_start, (void*)cbc_encrypt, (void*)cbc_decrypt, NULL, NULL, NULL};
 #endif /* DROPBEAR_ENABLE_CBC_MODE */
 
 const struct dropbear_cipher_mode dropbear_mode_none =
-	{void_start, void_cipher, void_cipher};
+	{void_start, void_cipher, void_cipher, NULL, NULL, NULL};
 
 #if DROPBEAR_ENABLE_CTR_MODE
 /* a wrapper to make ctr_start and cbc_start look the same */
@@ -101,7 +100,7 @@
 	return ctr_start(cipher, IV, key, keylen, num_rounds, CTR_COUNTER_BIG_ENDIAN, ctr);
 }
 const struct dropbear_cipher_mode dropbear_mode_ctr =
-	{(void*)dropbear_big_endian_ctr_start, (void*)ctr_encrypt, (void*)ctr_decrypt};
+	{(void*)dropbear_big_endian_ctr_start, (void*)ctr_encrypt, (void*)ctr_decrypt, NULL, NULL, NULL};
 #endif /* DROPBEAR_ENABLE_CTR_MODE */
 
 /* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc.
@@ -137,6 +136,19 @@
  * that is also supported by the server will get used. */
 
 algo_type sshciphers[] = {
+#if DROPBEAR_CHACHA20POLY1305
+	{"[email protected]", 0, &dropbear_chachapoly, 1, &dropbear_mode_chachapoly},
+#endif
+
+#if DROPBEAR_ENABLE_GCM_MODE
+#if DROPBEAR_AES128
+	{"[email protected]", 0, &dropbear_aes128, 1, &dropbear_mode_gcm},
+#endif
+#if DROPBEAR_AES256
+	{"[email protected]", 0, &dropbear_aes256, 1, &dropbear_mode_gcm},
+#endif
+#endif /* DROPBEAR_ENABLE_GCM_MODE */
+
 #if DROPBEAR_ENABLE_CTR_MODE
 #if DROPBEAR_AES128
 	{"aes128-ctr", 0, &dropbear_aes128, 1, &dropbear_mode_ctr},
@@ -169,15 +181,18 @@
 #if DROPBEAR_TWOFISH128
 	{"twofish128-cbc", 0, &dropbear_twofish128, 1, &dropbear_mode_cbc},
 #endif
+#endif /* DROPBEAR_ENABLE_CBC_MODE */
+
 #if DROPBEAR_3DES
+#if DROPBEAR_ENABLE_CTR_MODE
 	{"3des-ctr", 0, &dropbear_3des, 1, &dropbear_mode_ctr},
 #endif
-#if DROPBEAR_3DES
+#if DROPBEAR_ENABLE_CBC_MODE
 	{"3des-cbc", 0, &dropbear_3des, 1, &dropbear_mode_cbc},
 #endif
-#if DROPBEAR_BLOWFISH
-	{"blowfish-cbc", 0, &dropbear_blowfish, 1, &dropbear_mode_cbc},
-#endif
+#endif /* DROPBEAR_3DES */
+
+#if DROPBEAR_ENABLE_CBC_MODE
 #endif /* DROPBEAR_ENABLE_CBC_MODE */
 	{NULL, 0, NULL, 0, NULL}
 };
@@ -221,23 +236,31 @@
 	{NULL, 0, NULL, 0, NULL}
 };
 
-algo_type sshhostkey[] = {
+algo_type sigalgs[] = {
+#if DROPBEAR_ED25519
+	{"ssh-ed25519", DROPBEAR_SIGNATURE_ED25519, NULL, 1, NULL},
+#endif
 #if DROPBEAR_ECDSA
 #if DROPBEAR_ECC_256
-	{"ecdsa-sha2-nistp256", DROPBEAR_SIGNKEY_ECDSA_NISTP256, NULL, 1, NULL},
+	{"ecdsa-sha2-nistp256", DROPBEAR_SIGNATURE_ECDSA_NISTP256, NULL, 1, NULL},
 #endif
 #if DROPBEAR_ECC_384
-	{"ecdsa-sha2-nistp384", DROPBEAR_SIGNKEY_ECDSA_NISTP384, NULL, 1, NULL},
+	{"ecdsa-sha2-nistp384", DROPBEAR_SIGNATURE_ECDSA_NISTP384, NULL, 1, NULL},
 #endif
 #if DROPBEAR_ECC_521
-	{"ecdsa-sha2-nistp521", DROPBEAR_SIGNKEY_ECDSA_NISTP521, NULL, 1, NULL},
+	{"ecdsa-sha2-nistp521", DROPBEAR_SIGNATURE_ECDSA_NISTP521, NULL, 1, NULL},
 #endif
 #endif
 #if DROPBEAR_RSA
-	{"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1, NULL},
+#if DROPBEAR_RSA_SHA256
+	{"rsa-sha2-256", DROPBEAR_SIGNATURE_RSA_SHA256, NULL, 1, NULL},
+#endif
+#if DROPBEAR_RSA_SHA1
+	{"ssh-rsa", DROPBEAR_SIGNATURE_RSA_SHA1, NULL, 1, NULL},
+#endif
 #endif
 #if DROPBEAR_DSS
-	{"ssh-dss", DROPBEAR_SIGNKEY_DSS, NULL, 1, NULL},
+	{"ssh-dss", DROPBEAR_SIGNATURE_DSS, NULL, 1, NULL},
 #endif
 	{NULL, 0, NULL, 0, NULL}
 };
@@ -255,8 +278,6 @@
 static const struct dropbear_kex kex_dh_group16_sha512 = {DROPBEAR_KEX_NORMAL_DH, dh_p_16, DH_P_16_LEN, NULL, &sha512_desc };
 #endif
 
-/* These can't be const since dropbear_ecc_fill_dp() fills out
- ecc_curve at runtime */
 #if DROPBEAR_ECDH
 #if DROPBEAR_ECC_256
 static const struct dropbear_kex kex_ecdh_nistp256 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp256, &sha256_desc };
@@ -274,6 +295,7 @@
 static const struct dropbear_kex kex_curve25519 = {DROPBEAR_KEX_CURVE25519, NULL, 0, NULL, &sha256_desc };
 #endif
 
+/* data == NULL for non-kex algorithm identifiers */
 algo_type sshkex[] = {
 #if DROPBEAR_CURVE25519
 	{"curve25519-sha256", 0, &kex_curve25519, 1, NULL},
@@ -303,49 +325,122 @@
 	{"diffie-hellman-group16-sha512", 0, &kex_dh_group16_sha512, 1, NULL},
 #endif
 #if DROPBEAR_KEXGUESS2
-	{KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL},
+	{KEXGUESS2_ALGO_NAME, 0, NULL, 1, NULL},
+#endif
+#if DROPBEAR_EXT_INFO
+#if DROPBEAR_CLIENT
+	/* Set unusable by svr_algos_initialise() */
+	{SSH_EXT_INFO_C, 0, NULL, 1, NULL},
+#endif
 #endif
 	{NULL, 0, NULL, 0, NULL}
 };
 
-/* algolen specifies the length of algo, algos is our local list to match
- * against.
- * Returns DROPBEAR_SUCCESS if we have a match for algo, DROPBEAR_FAILURE
- * otherwise */
-int have_algo(const char* algo, size_t algolen, const algo_type algos[]) {
+/* Output a comma separated list of algorithms to a buffer */
+void buf_put_algolist_all(buffer * buf, const algo_type localalgos[], int useall) {
+	unsigned int i, len;
+	unsigned int donefirst = 0;
+	unsigned int startpos;
 
-	int i;
-
-	for (i = 0; algos[i].name != NULL; i++) {
-		if (strlen(algos[i].name) == algolen
-				&& (strncmp(algos[i].name, algo, algolen) == 0)) {
-			return DROPBEAR_SUCCESS;
+	startpos = buf->pos;
+	/* Placeholder for length */
+	buf_putint(buf, 0); 
+	for (i = 0; localalgos[i].name != NULL; i++) {
+		if (localalgos[i].usable || useall) {
+			if (donefirst) {
+				buf_putbyte(buf, ',');
+			}
+			donefirst = 1;
+			len = strlen(localalgos[i].name);
+			buf_putbytes(buf, (const unsigned char *) localalgos[i].name, len);
 		}
 	}
+	/* Fill out the length */
+	len = buf->pos - startpos - 4;
+	buf_setpos(buf, startpos);
+	buf_putint(buf, len);
+	TRACE(("algolist add %d '%*s'", len, len, buf_getptr(buf, len)))
+	buf_incrwritepos(buf, len);
+}
 
-	return DROPBEAR_FAILURE;
+void buf_put_algolist(buffer * buf, const algo_type localalgos[]) {
+	buf_put_algolist_all(buf, localalgos, 0);
 }
 
-/* Output a comma separated list of algorithms to a buffer */
-void buf_put_algolist(buffer * buf, const algo_type localalgos[]) {
+/* returns a list of pointers into algolist, of null-terminated names.
+   ret_list should be passed in with space for *ret_count elements,
+   on return *ret_count has the number of names filled.
+   algolist is modified. */
+static void get_algolist(char* algolist, unsigned int algolist_len,
+				const char* *ret_list, unsigned int *ret_count) {
+	unsigned int max_count = *ret_count;
+	unsigned int i;
 
-	unsigned int i, len;
-	unsigned int donefirst = 0;
-	buffer *algolist = NULL;
+	if (*ret_count == 0) {
+		return;
+	}
+	if (algolist_len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
+		*ret_count = 0;
+		}
 
-	algolist = buf_new(300);
-	for (i = 0; localalgos[i].name != NULL; i++) {
-		if (localalgos[i].usable) {
-			if (donefirst)
-				buf_putbyte(algolist, ',');
-			donefirst = 1;
-			len = strlen(localalgos[i].name);
-			buf_putbytes(algolist, (const unsigned char *) localalgos[i].name, len);
+	/* ret_list will contain a list of the strings parsed out.
+	   We will have at least one string (even if it's just "") */
+	ret_list[0] = algolist;
+	*ret_count = 1;
+	for (i = 0; i < algolist_len; i++) {
+		if (algolist[i] == '\0') {
+			/* someone is trying something strange */
+			*ret_count = 0;
+			return;
+	}
+
+		if (algolist[i] == ',') {
+			if (*ret_count >= max_count) {
+				/* Too many */
+				*ret_count = 0;
+				return;
+			}
+			algolist[i] = '\0';
+			ret_list[*ret_count] = &algolist[i+1];
+			(*ret_count)++;
 		}
 	}
-	buf_putstring(buf, (const char*)algolist->data, algolist->len);
-	TRACE(("algolist add '%*s'", algolist->len, algolist->data))
-	buf_free(algolist);
+}
+
+/* Return DROPBEAR_SUCCESS if the namelist contains algo,
+DROPBEAR_FAILURE otherwise. buf position is not incremented. */
+int buf_has_algo(buffer *buf, const char *algo) {
+	unsigned char* algolist = NULL;
+	unsigned int orig_pos = buf->pos;
+	unsigned int len, remotecount, i;
+	const char *remotenames[MAX_PROPOSED_ALGO];
+	int ret = DROPBEAR_FAILURE;
+
+	algolist = buf_getstring(buf, &len);
+	remotecount = MAX_PROPOSED_ALGO;
+	get_algolist(algolist, len, remotenames, &remotecount);
+	for (i = 0; i < remotecount; i++)
+	{
+		if (strcmp(remotenames[i], algo) == 0) {
+			ret = DROPBEAR_SUCCESS;
+			break;
+		}
+	}
+	if (algolist) {
+		m_free(algolist);
+	}
+	buf_setpos(buf, orig_pos);
+	return ret;
+}
+
+algo_type * first_usable_algo(algo_type algos[]) {
+	int i;
+	for (i = 0; algos[i].name != NULL; i++) {
+		if (algos[i].usable) {
+			return &algos[i];
+		}
+	}
+	return NULL;
 }
 
 /* match the first algorithm in the comma-separated list in buf which is
@@ -354,9 +449,7 @@
  * 0 otherwise. This is used for checking if the kexalgo/hostkeyalgos are
  * guessed correctly */
 algo_type * buf_match_algo(buffer* buf, algo_type localalgos[],
-		enum kexguess2_used *kexguess2, int *goodguess)
-{
-
+		int kexguess2, int *goodguess) {
 	char * algolist = NULL;
 	const char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO];
 	unsigned int len;
@@ -371,40 +464,8 @@
 	/* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */
 	algolist = buf_getstring(buf, &len);
 	TRACE(("buf_match_algo: %s", algolist))
-	if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
-		goto out;
-	}
-
-	/* remotenames will contain a list of the strings parsed out */
-	/* We will have at least one string (even if it's just "") */
-	remotenames[0] = algolist;
-	remotecount = 1;
-	for (i = 0; i < len; i++) {
-		if (algolist[i] == '\0') {
-			/* someone is trying something strange */
-			goto out;
-		}
-		if (algolist[i] == ',') {
-			algolist[i] = '\0';
-			remotenames[remotecount] = &algolist[i+1];
-			remotecount++;
-		}
-		if (remotecount >= MAX_PROPOSED_ALGO) {
-			break;
-		}
-	}
-	if (kexguess2 && *kexguess2 == KEXGUESS2_LOOK) {
-		for (i = 0; i < remotecount; i++)
-		{
-			if (strcmp(remotenames[i], KEXGUESS2_ALGO_NAME) == 0) {
-				*kexguess2 = KEXGUESS2_YES;
-				break;
-			}
-		}
-		if (*kexguess2 == KEXGUESS2_LOOK) {
-			*kexguess2 = KEXGUESS2_NO;
-		}
-	}
+	remotecount = MAX_PROPOSED_ALGO;
+	get_algolist(algolist, len, remotenames, &remotecount);
 
 	for (i = 0; localalgos[i].name != NULL; i++) {
 		if (localalgos[i].usable) {
@@ -436,12 +497,11 @@
 			}
 			if (strcmp(servnames[j], clinames[i]) == 0) {
 				/* set if it was a good guess */
-				if (goodguess && kexguess2) {
-					if (*kexguess2 == KEXGUESS2_YES) {
+				if (goodguess != NULL) {
+					if (kexguess2) {
 						if (i == 0) {
 							*goodguess = 1;
 						}
-
 					} else {
 						if (i == 0 && j == 0) {
 							*goodguess = 1;
--- a/common-kex.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/common-kex.c	Fri Jun 26 21:07:34 2020 +0800
@@ -36,6 +36,7 @@
 #include "dbrandom.h"
 #include "runopts.h"
 #include "ecc.h"
+#include "curve25519.h"
 #include "crypto_desc.h"
 
 static void kexinitialise(void);
@@ -64,7 +65,7 @@
 	buf_put_algolist(ses.writepayload, sshkex);
 
 	/* server_host_key_algorithms */
-	buf_put_algolist(ses.writepayload, sshhostkey);
+	buf_put_algolist(ses.writepayload, sigalgs);
 
 	/* encryption_algorithms_client_to_server */
 	buf_put_algolist(ses.writepayload, sshciphers);
@@ -109,8 +110,9 @@
 	ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
 
 	if (ses.send_kex_first_guess) {
-		ses.newkeys->algo_kex = sshkex[0].data;
-		ses.newkeys->algo_hostkey = sshhostkey[0].val;
+		ses.newkeys->algo_kex = first_usable_algo(sshkex)->data;
+		ses.newkeys->algo_signature = first_usable_algo(sigalgs)->val;
+		ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
 		ses.send_kex_first_guess();
 	}
 
@@ -151,6 +153,7 @@
 		TRACE(("switch_keys done"))
 		ses.keys->algo_kex = ses.newkeys->algo_kex;
 		ses.keys->algo_hostkey = ses.newkeys->algo_hostkey;
+		ses.keys->algo_signature = ses.newkeys->algo_signature;
 		ses.keys->allow_compress = 0;
 		m_free(ses.newkeys);
 		ses.newkeys = NULL;
@@ -172,6 +175,9 @@
 	
 	/* set up our state */
 	ses.kexstate.sentnewkeys = 1;
+	if (ses.kexstate.donefirstkex) {
+		ses.kexstate.donesecondkex = 1;
+	}
 	ses.kexstate.donefirstkex = 1;
 	ses.dataallowed = 1; /* we can send other packets again now */
 	gen_new_keys();
@@ -194,8 +200,6 @@
 
 /* Set up the kex for the first time */
 void kexfirstinitialise() {
-	ses.kexstate.donefirstkex = 0;
-
 #ifdef DISABLE_ZLIB
 	ses.compress_algos = ssh_nocompress;
 #else
@@ -328,9 +332,13 @@
 	hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D');
 
 	if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
-		int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
-		if (recv_cipher < 0)
-			dropbear_exit("Crypto error");
+		int recv_cipher = -1;
+		if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) {
+			recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
+			if (recv_cipher < 0) {
+				dropbear_exit("Crypto error");
+			}
+		}
 		if (ses.newkeys->recv.crypt_mode->start(recv_cipher, 
 				recv_IV, recv_key, 
 				ses.newkeys->recv.algo_crypt->keysize, 0, 
@@ -340,9 +348,13 @@
 	}
 
 	if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) {
-		int trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
-		if (trans_cipher < 0)
-			dropbear_exit("Crypto error");
+		int trans_cipher = -1;
+		if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) {
+			trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
+			if (trans_cipher < 0) {
+				dropbear_exit("Crypto error");
+			}
+		}
 		if (ses.newkeys->trans.crypt_mode->start(trans_cipher, 
 				trans_IV, trans_key, 
 				ses.newkeys->trans.algo_crypt->keysize, 0, 
@@ -536,6 +548,7 @@
 	TRACE(("leave recv_msg_kexinit"))
 }
 
+#if DROPBEAR_NORMAL_DH
 static void load_dh_p(mp_int * dh_p)
 {
 	bytes_to_mp(dh_p, ses.newkeys->algo_kex->dh_p_bytes, 
@@ -560,9 +573,7 @@
 	/* read the prime and generator*/
 	load_dh_p(&dh_p);
 	
-	if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) {
-		dropbear_exit("Diffie-Hellman error");
-	}
+	mp_set_ul(&dh_g, DH_G_VAL);
 
 	/* calculate q = (p-1)/2 */
 	/* dh_priv is just a temp var here */
@@ -646,6 +657,7 @@
 	/* calculate the hash H to sign */
 	finish_kexhashbuf();
 }
+#endif
 
 #if DROPBEAR_ECDH
 struct kex_ecdh_param *gen_kexecdh_param() {
@@ -703,23 +715,18 @@
 #endif /* DROPBEAR_ECDH */
 
 #if DROPBEAR_CURVE25519
-struct kex_curve25519_param *gen_kexcurve25519_param () {
+struct kex_curve25519_param *gen_kexcurve25519_param() {
 	/* Per http://cr.yp.to/ecdh.html */
 	struct kex_curve25519_param *param = m_malloc(sizeof(*param));
 	const unsigned char basepoint[32] = {9};
 
 	genrandom(param->priv, CURVE25519_LEN);
-	param->priv[0] &= 248;
-	param->priv[31] &= 127;
-	param->priv[31] |= 64;
-
-	curve25519_donna(param->pub, param->priv, basepoint);
+	dropbear_curve25519_scalarmult(param->pub, param->priv, basepoint);
 
 	return param;
 }
 
-void free_kexcurve25519_param(struct kex_curve25519_param *param)
-{
+void free_kexcurve25519_param(struct kex_curve25519_param *param) {
 	m_burn(param->priv, CURVE25519_LEN);
 	m_free(param);
 }
@@ -736,7 +743,7 @@
 		dropbear_exit("Bad curve25519");
 	}
 
-	curve25519_donna(out, param->priv, buf_pub_them->data);
+	dropbear_curve25519_scalarmult(out, param->priv, buf_pub_them->data);
 
 	if (constant_time_memcmp(zeroes, out, CURVE25519_LEN) == 0) {
 		dropbear_exit("Bad curve25519");
@@ -822,21 +829,36 @@
 	int goodguess = 0;
 	int allgood = 1; /* we AND this with each goodguess and see if its still
 						true after */
-
-#if DROPBEAR_KEXGUESS2
-	enum kexguess2_used kexguess2 = KEXGUESS2_LOOK;
-#else
-	enum kexguess2_used kexguess2 = KEXGUESS2_NO;
-#endif
+	int kexguess2 = 0;
 
 	buf_incrpos(ses.payload, 16); /* start after the cookie */
 
 	memset(ses.newkeys, 0x0, sizeof(*ses.newkeys));
 
 	/* kex_algorithms */
-	algo = buf_match_algo(ses.payload, sshkex, &kexguess2, &goodguess);
+#if DROPBEAR_KEXGUESS2
+	if (buf_has_algo(ses.payload, KEXGUESS2_ALGO_NAME) == DROPBEAR_SUCCESS) {
+		kexguess2 = 1;
+	}
+#endif
+
+#if DROPBEAR_EXT_INFO
+	/* Determine if SSH_MSG_EXT_INFO messages should be sent.
+	Should be done for the first key exchange. Only required on server side
+    for server-sig-algs */
+	if (IS_DROPBEAR_SERVER) {
+		if (!ses.kexstate.donefirstkex) {
+			if (buf_has_algo(ses.payload, SSH_EXT_INFO_C) == DROPBEAR_SUCCESS) {
+				ses.allow_ext_info = 1;
+			}
+		}
+	}
+#endif
+
+	algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
 	allgood &= goodguess;
-	if (algo == NULL || algo->val == KEXGUESS2_ALGO_ID) {
+	if (algo == NULL || algo->data == NULL) {
+		/* kexguess2, ext-info-c, ext-info-s should not match negotiation */
 		erralgo = "kex";
 		goto error;
 	}
@@ -845,17 +867,18 @@
 	ses.newkeys->algo_kex = algo->data;
 
 	/* server_host_key_algorithms */
-	algo = buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess);
+	algo = buf_match_algo(ses.payload, sigalgs, kexguess2, &goodguess);
 	allgood &= goodguess;
 	if (algo == NULL) {
 		erralgo = "hostkey";
 		goto error;
 	}
-	TRACE(("hostkey algo %s", algo->name))
-	ses.newkeys->algo_hostkey = algo->val;
+	TRACE(("signature algo %s", algo->name))
+	ses.newkeys->algo_signature = algo->val;
+	ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
 
 	/* encryption_algorithms_client_to_server */
-	c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL);
+	c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
 	if (c2s_cipher_algo == NULL) {
 		erralgo = "enc c->s";
 		goto error;
@@ -863,7 +886,7 @@
 	TRACE(("enc c2s is  %s", c2s_cipher_algo->name))
 
 	/* encryption_algorithms_server_to_client */
-	s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL);
+	s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
 	if (s2c_cipher_algo == NULL) {
 		erralgo = "enc s->c";
 		goto error;
@@ -871,23 +894,33 @@
 	TRACE(("enc s2c is  %s", s2c_cipher_algo->name))
 
 	/* mac_algorithms_client_to_server */
-	c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL);
+	c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
+#if DROPBEAR_AEAD_MODE
+	if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) {
+		c2s_hash_algo = NULL;
+	} else
+#endif
 	if (c2s_hash_algo == NULL) {
 		erralgo = "mac c->s";
 		goto error;
 	}
-	TRACE(("hash c2s is  %s", c2s_hash_algo->name))
+	TRACE(("hash c2s is  %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>"))
 
 	/* mac_algorithms_server_to_client */
-	s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL);
+	s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
+#if DROPBEAR_AEAD_MODE
+	if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) {
+		s2c_hash_algo = NULL;
+	} else
+#endif
 	if (s2c_hash_algo == NULL) {
 		erralgo = "mac s->c";
 		goto error;
 	}
-	TRACE(("hash s2c is  %s", s2c_hash_algo->name))
+	TRACE(("hash s2c is  %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>"))
 
 	/* compression_algorithms_client_to_server */
-	c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL);
+	c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL);
 	if (c2s_comp_algo == NULL) {
 		erralgo = "comp c->s";
 		goto error;
@@ -895,7 +928,7 @@
 	TRACE(("hash c2s is  %s", c2s_comp_algo->name))
 
 	/* compression_algorithms_server_to_client */
-	s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL);
+	s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL);
 	if (s2c_comp_algo == NULL) {
 		erralgo = "comp s->c";
 		goto error;
@@ -929,8 +962,14 @@
 		ses.newkeys->trans.crypt_mode =
 			(struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
 		ses.newkeys->recv.algo_mac = 
+#if DROPBEAR_AEAD_MODE
+			s2c_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
+#endif
 			(struct dropbear_hash*)s2c_hash_algo->data;
 		ses.newkeys->trans.algo_mac = 
+#if DROPBEAR_AEAD_MODE
+			c2s_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
+#endif
 			(struct dropbear_hash*)c2s_hash_algo->data;
 		ses.newkeys->recv.algo_comp = s2c_comp_algo->val;
 		ses.newkeys->trans.algo_comp = c2s_comp_algo->val;
@@ -945,8 +984,14 @@
 		ses.newkeys->trans.crypt_mode =
 			(struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
 		ses.newkeys->recv.algo_mac = 
+#if DROPBEAR_AEAD_MODE
+			c2s_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
+#endif
 			(struct dropbear_hash*)c2s_hash_algo->data;
 		ses.newkeys->trans.algo_mac = 
+#if DROPBEAR_AEAD_MODE
+			s2c_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
+#endif
 			(struct dropbear_hash*)s2c_hash_algo->data;
 		ses.newkeys->recv.algo_comp = c2s_comp_algo->val;
 		ses.newkeys->trans.algo_comp = s2c_comp_algo->val;
--- a/common-runopts.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/common-runopts.c	Fri Jun 26 21:07:34 2020 +0800
@@ -64,44 +64,35 @@
 
 #if DROPBEAR_USER_ALGO_LIST
 void
-parse_ciphers_macs()
-{
-	if (opts.cipher_list)
-	{
-		if (strcmp(opts.cipher_list, "help") == 0)
-		{
+parse_ciphers_macs() {
+	int printed_help = 0;
+	if (opts.cipher_list) {
+		if (strcmp(opts.cipher_list, "help") == 0) {
 			char *ciphers = algolist_string(sshciphers);
-			dropbear_log(LOG_INFO, "Available ciphers:\n%s\n", ciphers);
+			dropbear_log(LOG_INFO, "Available ciphers: %s", ciphers);
 			m_free(ciphers);
-			dropbear_exit(".");
-		}
-
-		if (strcmp(opts.cipher_list, "none") == 0)
-		{
-			/* Encryption is required during authentication */
-			opts.cipher_list = "none,aes128-ctr";
-		}
-
-		if (check_user_algos(opts.cipher_list, sshciphers, "cipher") == 0)
-		{
-			dropbear_exit("No valid ciphers specified for '-c'");
+			printed_help = 1;
+		} else {
+			if (check_user_algos(opts.cipher_list, sshciphers, "cipher") == 0) {
+				dropbear_exit("No valid ciphers specified for '-c'");
+			}
 		}
 	}
 
-	if (opts.mac_list)
-	{
-		if (strcmp(opts.mac_list, "help") == 0)
-		{
+	if (opts.mac_list) {
+		if (strcmp(opts.mac_list, "help") == 0) {
 			char *macs = algolist_string(sshhashes);
-			dropbear_log(LOG_INFO, "Available MACs:\n%s\n", macs);
+			dropbear_log(LOG_INFO, "Available MACs: %s", macs);
 			m_free(macs);
-			dropbear_exit(".");
+			printed_help = 1;
+		} else {
+			if (check_user_algos(opts.mac_list, sshhashes, "MAC") == 0) {
+				dropbear_exit("No valid MACs specified for '-m'");
+			}
 		}
-
-		if (check_user_algos(opts.mac_list, sshhashes, "MAC") == 0)
-		{
-			dropbear_exit("No valid MACs specified for '-m'");
-		}
+	}
+	if (printed_help) {
+		dropbear_exit(".");
 	}
 }
 #endif
--- a/common-session.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/common-session.c	Fri Jun 26 21:07:34 2020 +0800
@@ -147,6 +147,10 @@
 
 	ses.allowprivport = 0;
 
+#if DROPBEAR_PLUGIN
+        ses.plugin_session = NULL;
+#endif
+
 	TRACE(("leave session_init"))
 }
 
@@ -366,8 +370,11 @@
 	int len = 0;
 	char done = 0;
 	int i;
-	/* If they send more than 50 lines, something is wrong */
-	for (i = 0; i < 50; i++) {
+
+	/* Servers may send other lines of data before sending the
+	 * version string, client must be able to process such lines.
+	 * If they send more than 50 lines, something is wrong */
+	for (i = IS_DROPBEAR_CLIENT ? 50 : 1; i > 0; i--) {
 		len = ident_readln(ses.sock_in, linebuf, sizeof(linebuf));
 
 		if (len < 0 && errno != EINTR) {
--- a/config.guess	Thu Mar 21 23:28:59 2019 +0800
+++ b/config.guess	Fri Jun 26 21:07:34 2020 +0800
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2013 Free Software Foundation, Inc.
+#   Copyright 1992-2019 Free Software Foundation, Inc.
 
-timestamp='2013-06-10'
+timestamp='2019-03-04'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -24,12 +24,12 @@
 # program.  This Exception is an additional permission under section 7
 # of the GNU General Public License, version 3 ("GPLv3").
 #
-# Originally written by Per Bothner.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 #
-# Please send patches with a ChangeLog entry to [email protected].
+# Please send patches to <[email protected]>.
 
 
 me=`echo "$0" | sed -e 's,.*/,,'`
@@ -39,7 +39,7 @@
 
 Output the configuration name of the system \`$me' is run on.
 
-Operation modes:
+Options:
   -h, --help         print this help, then exit
   -t, --time-stamp   print date of last modification, then exit
   -v, --version      print version number, then exit
@@ -50,7 +50,7 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2019 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -84,8 +84,6 @@
   exit 1
 fi
 
-trap 'exit 1' 1 2 15
-
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
 # temporary files to be created and, as you can see below, it is a
@@ -96,34 +94,38 @@
 
 # Portable tmp directory creation inspired by the Autoconf team.
 
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > $dummy.c ;
-	for c in cc gcc c89 c99 ; do
-	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
-	     CC_FOR_BUILD="$c"; break ;
-	  fi ;
-	done ;
-	if test x"$CC_FOR_BUILD" = x ; then
-	  CC_FOR_BUILD=no_compiler_found ;
-	fi
-	;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+
+set_cc_for_build() {
+    : "${TMPDIR=/tmp}"
+    # shellcheck disable=SC2039
+    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+    dummy=$tmp/dummy
+    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+	,,)    echo "int x;" > "$dummy.c"
+	       for driver in cc gcc c89 c99 ; do
+		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+		       CC_FOR_BUILD="$driver"
+		       break
+		   fi
+	       done
+	       if test x"$CC_FOR_BUILD" = x ; then
+		   CC_FOR_BUILD=no_compiler_found
+	       fi
+	       ;;
+	,,*)   CC_FOR_BUILD=$CC ;;
+	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+    esac
+}
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # ([email protected] 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
 	PATH=$PATH:/.attbin ; export PATH
 fi
 
@@ -132,14 +134,14 @@
 UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-case "${UNAME_SYSTEM}" in
+case "$UNAME_SYSTEM" in
 Linux|GNU|GNU/*)
 	# If the system lacks a compiler, then just pick glibc.
 	# We could probably try harder.
 	LIBC=gnu
 
-	eval $set_cc_for_build
-	cat <<-EOF > $dummy.c
+	set_cc_for_build
+	cat <<-EOF > "$dummy.c"
 	#include <features.h>
 	#if defined(__UCLIBC__)
 	LIBC=uclibc
@@ -149,13 +151,20 @@
 	LIBC=gnu
 	#endif
 	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+
+	# If ldd exists, use it to detect musl libc.
+	if command -v ldd >/dev/null && \
+		ldd --version 2>&1 | grep -q ^musl
+	then
+	    LIBC=musl
+	fi
 	;;
 esac
 
 # Note: order is significant - the case branches are not exclusive.
 
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *:NetBSD:*:*)
 	# NetBSD (nbsd) targets should (where applicable) match one or
 	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -168,21 +177,31 @@
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
-	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
-	case "${UNAME_MACHINE_ARCH}" in
+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	    "/sbin/$sysctl" 2>/dev/null || \
+	    "/usr/sbin/$sysctl" 2>/dev/null || \
+	    echo unknown)`
+	case "$UNAME_MACHINE_ARCH" in
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
-	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	    earmv*)
+		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+		machine="${arch}${endian}"-unknown
+		;;
+	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
-	# to ELF recently, or will in the future.
-	case "${UNAME_MACHINE_ARCH}" in
+	# to ELF recently (or will in the future) and ABI.
+	case "$UNAME_MACHINE_ARCH" in
+	    earm*)
+		os=netbsdelf
+		;;
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-		eval $set_cc_for_build
+		set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
 		then
@@ -197,44 +216,67 @@
 		os=netbsd
 		;;
 	esac
+	# Determine ABI tags.
+	case "$UNAME_MACHINE_ARCH" in
+	    earm*)
+		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+		;;
+	esac
 	# The OS release
 	# Debian GNU/NetBSD machines have a different userland, and
 	# thus, need a distinct triplet. However, they do not need
 	# kernel version information, so it can be replaced with a
 	# suitable tag, in the style of linux-gnu.
-	case "${UNAME_VERSION}" in
+	case "$UNAME_VERSION" in
 	    Debian*)
 		release='-gnu'
 		;;
 	    *)
-		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}"
+	echo "$machine-${os}${release}${abi-}"
 	exit ;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
 	exit ;;
     *:OpenBSD:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
+	exit ;;
+    *:LibertyBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+	echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+	exit ;;
+    *:MidnightBSD:*:*)
+	echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
 	exit ;;
     *:ekkoBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
 	exit ;;
     *:SolidBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
 	exit ;;
     macppc:MirBSD:*:*)
-	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
 	exit ;;
     *:MirBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
+	exit ;;
+    *:Sortix:*:*)
+	echo "$UNAME_MACHINE"-unknown-sortix
 	exit ;;
+    *:Redox:*:*)
+	echo "$UNAME_MACHINE"-unknown-redox
+	exit ;;
+    mips:OSF1:*.*)
+        echo mips-dec-osf1
+        exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
@@ -251,63 +293,54 @@
 	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
 	case "$ALPHA_CPU_TYPE" in
 	    "EV4 (21064)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "EV4.5 (21064)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "LCA4 (21066/21068)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "EV5 (21164)")
-		UNAME_MACHINE="alphaev5" ;;
+		UNAME_MACHINE=alphaev5 ;;
 	    "EV5.6 (21164A)")
-		UNAME_MACHINE="alphaev56" ;;
+		UNAME_MACHINE=alphaev56 ;;
 	    "EV5.6 (21164PC)")
-		UNAME_MACHINE="alphapca56" ;;
+		UNAME_MACHINE=alphapca56 ;;
 	    "EV5.7 (21164PC)")
-		UNAME_MACHINE="alphapca57" ;;
+		UNAME_MACHINE=alphapca57 ;;
 	    "EV6 (21264)")
-		UNAME_MACHINE="alphaev6" ;;
+		UNAME_MACHINE=alphaev6 ;;
 	    "EV6.7 (21264A)")
-		UNAME_MACHINE="alphaev67" ;;
+		UNAME_MACHINE=alphaev67 ;;
 	    "EV6.8CB (21264C)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.8AL (21264B)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.8CX (21264D)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.9A (21264/EV69A)")
-		UNAME_MACHINE="alphaev69" ;;
+		UNAME_MACHINE=alphaev69 ;;
 	    "EV7 (21364)")
-		UNAME_MACHINE="alphaev7" ;;
+		UNAME_MACHINE=alphaev7 ;;
 	    "EV7.9 (21364A)")
-		UNAME_MACHINE="alphaev79" ;;
+		UNAME_MACHINE=alphaev79 ;;
 	esac
 	# A Pn.n version is a patched version.
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
 	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
 	exitcode=$?
 	trap '' 0
 	exit $exitcode ;;
-    Alpha\ *:Windows_NT*:*)
-	# How do we know it's Interix rather than the generic POSIX subsystem?
-	# Should we change UNAME_MACHINE based on the output of uname instead
-	# of the specific Alpha model?
-	echo alpha-pc-interix
-	exit ;;
-    21064:Windows_NT:50:3)
-	echo alpha-dec-winnt3.5
-	exit ;;
     Amiga*:UNIX_System_V:4.0:*)
 	echo m68k-unknown-sysv4
 	exit ;;
     *:[Aa]miga[Oo][Ss]:*:*)
-	echo ${UNAME_MACHINE}-unknown-amigaos
+	echo "$UNAME_MACHINE"-unknown-amigaos
 	exit ;;
     *:[Mm]orph[Oo][Ss]:*:*)
-	echo ${UNAME_MACHINE}-unknown-morphos
+	echo "$UNAME_MACHINE"-unknown-morphos
 	exit ;;
     *:OS/390:*:*)
 	echo i370-ibm-openedition
@@ -319,7 +352,7 @@
 	echo powerpc-ibm-os400
 	exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-	echo arm-acorn-riscix${UNAME_RELEASE}
+	echo arm-acorn-riscix"$UNAME_RELEASE"
 	exit ;;
     arm*:riscos:*:*|arm*:RISCOS:*:*)
 	echo arm-unknown-riscos
@@ -346,38 +379,38 @@
 	    sparc) echo sparc-icl-nx7; exit ;;
 	esac ;;
     s390x:SunOS:*:*)
-	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
 	exit ;;
     sun4H:SunOS:5.*:*)
-	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
 	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
 	exit ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-	echo i386-pc-auroraux${UNAME_RELEASE}
+	echo i386-pc-auroraux"$UNAME_RELEASE"
 	exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	eval $set_cc_for_build
-	SUN_ARCH="i386"
+	set_cc_for_build
+	SUN_ARCH=i386
 	# If there is a compiler, see if it is configured for 64-bit objects.
 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
 		grep IS_64BIT_ARCH >/dev/null
 	    then
-		SUN_ARCH="x86_64"
+		SUN_ARCH=x86_64
 	    fi
 	fi
-	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
 	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
-	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
 	exit ;;
     sun4*:SunOS:*:*)
 	case "`/usr/bin/arch -k`" in
@@ -386,25 +419,25 @@
 		;;
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
-	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
 	exit ;;
     sun3*:SunOS:*:*)
-	echo m68k-sun-sunos${UNAME_RELEASE}
+	echo m68k-sun-sunos"$UNAME_RELEASE"
 	exit ;;
     sun*:*:4.2BSD:*)
 	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
 	case "`/bin/arch`" in
 	    sun3)
-		echo m68k-sun-sunos${UNAME_RELEASE}
+		echo m68k-sun-sunos"$UNAME_RELEASE"
 		;;
 	    sun4)
-		echo sparc-sun-sunos${UNAME_RELEASE}
+		echo sparc-sun-sunos"$UNAME_RELEASE"
 		;;
 	esac
 	exit ;;
     aushp:SunOS:*:*)
-	echo sparc-auspex-sunos${UNAME_RELEASE}
+	echo sparc-auspex-sunos"$UNAME_RELEASE"
 	exit ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
@@ -415,44 +448,44 @@
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-	echo m68k-atari-mint${UNAME_RELEASE}
+	echo m68k-atari-mint"$UNAME_RELEASE"
 	exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-	echo m68k-atari-mint${UNAME_RELEASE}
+	echo m68k-atari-mint"$UNAME_RELEASE"
 	exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-	echo m68k-atari-mint${UNAME_RELEASE}
+	echo m68k-atari-mint"$UNAME_RELEASE"
 	exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-	echo m68k-milan-mint${UNAME_RELEASE}
+	echo m68k-milan-mint"$UNAME_RELEASE"
 	exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-	echo m68k-hades-mint${UNAME_RELEASE}
+	echo m68k-hades-mint"$UNAME_RELEASE"
 	exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-	echo m68k-unknown-mint${UNAME_RELEASE}
+	echo m68k-unknown-mint"$UNAME_RELEASE"
 	exit ;;
     m68k:machten:*:*)
-	echo m68k-apple-machten${UNAME_RELEASE}
+	echo m68k-apple-machten"$UNAME_RELEASE"
 	exit ;;
     powerpc:machten:*:*)
-	echo powerpc-apple-machten${UNAME_RELEASE}
+	echo powerpc-apple-machten"$UNAME_RELEASE"
 	exit ;;
     RISC*:Mach:*:*)
 	echo mips-dec-mach_bsd4.3
 	exit ;;
     RISC*:ULTRIX:*:*)
-	echo mips-dec-ultrix${UNAME_RELEASE}
+	echo mips-dec-ultrix"$UNAME_RELEASE"
 	exit ;;
     VAX*:ULTRIX*:*:*)
-	echo vax-dec-ultrix${UNAME_RELEASE}
+	echo vax-dec-ultrix"$UNAME_RELEASE"
 	exit ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
-	echo clipper-intergraph-clix${UNAME_RELEASE}
+	echo clipper-intergraph-clix"$UNAME_RELEASE"
 	exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
+	set_cc_for_build
+	sed 's/^	//' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
 	int main (int argc, char *argv[]) {
@@ -461,23 +494,23 @@
 #endif
 	#if defined (host_mips) && defined (MIPSEB)
 	#if defined (SYSTYPE_SYSV)
-	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	  printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
 	#endif
 	#if defined (SYSTYPE_SVR4)
-	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	  printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
 	#endif
 	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
-	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	  printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
 	#endif
 	#endif
 	  exit (-1);
 	}
 EOF
-	$CC_FOR_BUILD -o $dummy $dummy.c &&
-	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
 	    { echo "$SYSTEM_NAME"; exit; }
-	echo mips-mips-riscos${UNAME_RELEASE}
+	echo mips-mips-riscos"$UNAME_RELEASE"
 	exit ;;
     Motorola:PowerMAX_OS:*:*)
 	echo powerpc-motorola-powermax
@@ -503,17 +536,17 @@
     AViiON:dgux:*:*)
 	# DG/UX returns AViiON for all architectures
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
 	then
-	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
-	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+	       [ "$TARGET_BINARY_INTERFACE"x = x ]
 	    then
-		echo m88k-dg-dgux${UNAME_RELEASE}
+		echo m88k-dg-dgux"$UNAME_RELEASE"
 	    else
-		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+		echo m88k-dg-dguxbcs"$UNAME_RELEASE"
 	    fi
 	else
-	    echo i586-dg-dgux${UNAME_RELEASE}
+	    echo i586-dg-dgux"$UNAME_RELEASE"
 	fi
 	exit ;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
@@ -530,7 +563,7 @@
 	echo m68k-tektronix-bsd
 	exit ;;
     *:IRIX*:*:*)
-	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
 	exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
 	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
@@ -542,14 +575,14 @@
 	if [ -x /usr/bin/oslevel ] ; then
 		IBM_REV=`/usr/bin/oslevel`
 	else
-		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
-	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
 	exit ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-		eval $set_cc_for_build
-		sed 's/^		//' << EOF >$dummy.c
+		set_cc_for_build
+		sed 's/^		//' << EOF > "$dummy.c"
 		#include <sys/systemcfg.h>
 
 		main()
@@ -560,7 +593,7 @@
 			exit(0);
 			}
 EOF
-		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
 		then
 			echo "$SYSTEM_NAME"
 		else
@@ -574,26 +607,27 @@
 	exit ;;
     *:AIX:*:[4567])
 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
-	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/oslevel ] ; then
-		IBM_REV=`/usr/bin/oslevel`
+	if [ -x /usr/bin/lslpp ] ; then
+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
 	else
-		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
-	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
 	exit ;;
     *:AIX:*:*)
 	echo rs6000-ibm-aix
 	exit ;;
-    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+    ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
 	echo romp-ibm-bsd4.4
 	exit ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to
 	exit ;;                             # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
 	echo rs6000-bull-bosx
@@ -608,28 +642,28 @@
 	echo m68k-hp-bsd4.4
 	exit ;;
     9000/[34678]??:HP-UX:*:*)
-	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-	case "${UNAME_MACHINE}" in
-	    9000/31? )            HP_ARCH=m68000 ;;
-	    9000/[34]?? )         HP_ARCH=m68k ;;
+	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	case "$UNAME_MACHINE" in
+	    9000/31?)            HP_ARCH=m68000 ;;
+	    9000/[34]??)         HP_ARCH=m68k ;;
 	    9000/[678][0-9][0-9])
 		if [ -x /usr/bin/getconf ]; then
 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
 		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-		    case "${sc_cpu_version}" in
-		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		    case "$sc_cpu_version" in
+		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
 		      532)                      # CPU_PA_RISC2_0
-			case "${sc_kernel_bits}" in
-			  32) HP_ARCH="hppa2.0n" ;;
-			  64) HP_ARCH="hppa2.0w" ;;
-			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			case "$sc_kernel_bits" in
+			  32) HP_ARCH=hppa2.0n ;;
+			  64) HP_ARCH=hppa2.0w ;;
+			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
 			esac ;;
 		    esac
 		fi
-		if [ "${HP_ARCH}" = "" ]; then
-		    eval $set_cc_for_build
-		    sed 's/^		//' << EOF >$dummy.c
+		if [ "$HP_ARCH" = "" ]; then
+		    set_cc_for_build
+		    sed 's/^		//' << EOF > "$dummy.c"
 
 		#define _HPUX_SOURCE
 		#include <stdlib.h>
@@ -662,13 +696,13 @@
 		    exit (0);
 		}
 EOF
-		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
-	if [ ${HP_ARCH} = "hppa2.0w" ]
+	if [ "$HP_ARCH" = hppa2.0w ]
 	then
-	    eval $set_cc_for_build
+	    set_cc_for_build
 
 	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
 	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -679,23 +713,23 @@
 	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
 	    # => hppa64-hp-hpux11.23
 
-	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
 		grep -q __LP64__
 	    then
-		HP_ARCH="hppa2.0w"
+		HP_ARCH=hppa2.0w
 	    else
-		HP_ARCH="hppa64"
+		HP_ARCH=hppa64
 	    fi
 	fi
-	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
 	exit ;;
     ia64:HP-UX:*:*)
-	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-	echo ia64-hp-hpux${HPUX_REV}
+	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux"$HPUX_REV"
 	exit ;;
     3050*:HI-UX:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
+	set_cc_for_build
+	sed 's/^	//' << EOF > "$dummy.c"
 	#include <unistd.h>
 	int
 	main ()
@@ -720,11 +754,11 @@
 	  exit (0);
 	}
 EOF
-	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
 		{ echo "$SYSTEM_NAME"; exit; }
 	echo unknown-hitachi-hiuxwe2
 	exit ;;
-    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
 	echo hppa1.1-hp-bsd
 	exit ;;
     9000/8??:4.3bsd:*:*)
@@ -733,7 +767,7 @@
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
 	echo hppa1.0-hp-mpeix
 	exit ;;
-    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
 	echo hppa1.1-hp-osf
 	exit ;;
     hp8??:OSF1:*:*)
@@ -741,9 +775,9 @@
 	exit ;;
     i*86:OSF1:*:*)
 	if [ -x /usr/sbin/sysversion ] ; then
-	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	    echo "$UNAME_MACHINE"-unknown-osf1mk
 	else
-	    echo ${UNAME_MACHINE}-unknown-osf1
+	    echo "$UNAME_MACHINE"-unknown-osf1
 	fi
 	exit ;;
     parisc*:Lites*:*:*)
@@ -768,127 +802,120 @@
 	echo c4-convex-bsd
 	exit ;;
     CRAY*Y-MP:*:*:*)
-	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     CRAY*[A-Z]90:*:*:*)
-	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
 	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
 	      -e 's/\.[^.]*$/.X/'
 	exit ;;
     CRAY*TS:*:*:*)
-	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     CRAY*T3E:*:*:*)
-	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     CRAY*SV1:*:*:*)
-	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     *:UNICOS/mp:*:*)
-	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
 	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     5000:UNIX_System_V:4.*:*)
-	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
 	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
 	exit ;;
     sparc*:BSD/OS:*:*)
-	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	echo sparc-unknown-bsdi"$UNAME_RELEASE"
 	exit ;;
     *:BSD/OS:*:*)
-	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
+	exit ;;
+    arm:FreeBSD:*:*)
+	UNAME_PROCESSOR=`uname -p`
+	set_cc_for_build
+	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_PCS_VFP
+	then
+	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi
+	else
+	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf
+	fi
 	exit ;;
     *:FreeBSD:*:*)
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	case ${UNAME_PROCESSOR} in
+	case "$UNAME_PROCESSOR" in
 	    amd64)
-		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-	    *)
-		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+		UNAME_PROCESSOR=x86_64 ;;
+	    i386)
+		UNAME_PROCESSOR=i586 ;;
 	esac
+	echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
 	exit ;;
     i*:CYGWIN*:*)
-	echo ${UNAME_MACHINE}-pc-cygwin
+	echo "$UNAME_MACHINE"-pc-cygwin
 	exit ;;
     *:MINGW64*:*)
-	echo ${UNAME_MACHINE}-pc-mingw64
+	echo "$UNAME_MACHINE"-pc-mingw64
 	exit ;;
     *:MINGW*:*)
-	echo ${UNAME_MACHINE}-pc-mingw32
+	echo "$UNAME_MACHINE"-pc-mingw32
 	exit ;;
-    i*:MSYS*:*)
-	echo ${UNAME_MACHINE}-pc-msys
-	exit ;;
-    i*:windows32*:*)
-	# uname -m includes "-pc" on this system.
-	echo ${UNAME_MACHINE}-mingw32
+    *:MSYS*:*)
+	echo "$UNAME_MACHINE"-pc-msys
 	exit ;;
     i*:PW*:*)
-	echo ${UNAME_MACHINE}-pc-pw32
+	echo "$UNAME_MACHINE"-pc-pw32
 	exit ;;
     *:Interix*:*)
-	case ${UNAME_MACHINE} in
+	case "$UNAME_MACHINE" in
 	    x86)
-		echo i586-pc-interix${UNAME_RELEASE}
+		echo i586-pc-interix"$UNAME_RELEASE"
 		exit ;;
 	    authenticamd | genuineintel | EM64T)
-		echo x86_64-unknown-interix${UNAME_RELEASE}
+		echo x86_64-unknown-interix"$UNAME_RELEASE"
 		exit ;;
 	    IA64)
-		echo ia64-unknown-interix${UNAME_RELEASE}
+		echo ia64-unknown-interix"$UNAME_RELEASE"
 		exit ;;
 	esac ;;
-    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
-	echo i${UNAME_MACHINE}-pc-mks
-	exit ;;
-    8664:Windows_NT:*)
-	echo x86_64-pc-mks
-	exit ;;
-    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
-	# How do we know it's Interix rather than the generic POSIX subsystem?
-	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
-	# UNAME_MACHINE based on the output of uname instead of i386?
-	echo i586-pc-interix
-	exit ;;
     i*:UWIN*:*)
-	echo ${UNAME_MACHINE}-pc-uwin
+	echo "$UNAME_MACHINE"-pc-uwin
 	exit ;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-	echo x86_64-unknown-cygwin
-	exit ;;
-    p*:CYGWIN*:*)
-	echo powerpcle-unknown-cygwin
+	echo x86_64-pc-cygwin
 	exit ;;
     prep*:SunOS:5.*:*)
-	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
 	exit ;;
     *:GNU:*:*)
 	# the GNU system
-	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
 	exit ;;
     *:GNU/*:*:*)
 	# other systems with GNU libc and userland
-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
 	exit ;;
-    i*86:Minix:*:*)
-	echo ${UNAME_MACHINE}-pc-minix
+    *:Minix:*:*)
+	echo "$UNAME_MACHINE"-unknown-minix
 	exit ;;
     aarch64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     aarch64_be:Linux:*:*)
 	UNAME_MACHINE=aarch64_be
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     alpha:Linux:*:*)
 	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -901,129 +928,169 @@
 	  EV68*) UNAME_MACHINE=alphaev68 ;;
 	esac
 	objdump --private-headers /bin/sh | grep -q ld.so.1
-	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     arc:Linux:*:* | arceb:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     arm*:Linux:*:*)
-	eval $set_cc_for_build
+	set_cc_for_build
 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
 	    | grep -q __ARM_EABI__
 	then
-	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	    echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	else
 	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
 		| grep -q __ARM_PCS_VFP
 	    then
-		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
 	    else
-		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
 	    fi
 	fi
 	exit ;;
     avr32*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     cris:Linux:*:*)
-	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
 	exit ;;
     crisv32:Linux:*:*)
-	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+	exit ;;
+    e2k:Linux:*:*)
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     frv:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     hexagon:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     i*86:Linux:*:*)
-	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
 	exit ;;
     ia64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
+    k1om:Linux:*:*)
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     m32r*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     m68*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
+	set_cc_for_build
+	IS_GLIBC=0
+	test x"${LIBC}" = xgnu && IS_GLIBC=1
+	sed 's/^	//' << EOF > "$dummy.c"
 	#undef CPU
-	#undef ${UNAME_MACHINE}
-	#undef ${UNAME_MACHINE}el
+	#undef mips
+	#undef mipsel
+	#undef mips64
+	#undef mips64el
+	#if ${IS_GLIBC} && defined(_ABI64)
+	LIBCABI=gnuabi64
+	#else
+	#if ${IS_GLIBC} && defined(_ABIN32)
+	LIBCABI=gnuabin32
+	#else
+	LIBCABI=${LIBC}
+	#endif
+	#endif
+
+	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa64r6
+	#else
+	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa32r6
+	#else
+	#if defined(__mips64)
+	CPU=mips64
+	#else
+	CPU=mips
+	#endif
+	#endif
+	#endif
+
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=${UNAME_MACHINE}el
+	MIPS_ENDIAN=el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=${UNAME_MACHINE}
+	MIPS_ENDIAN=
 	#else
-	CPU=
+	MIPS_ENDIAN=
 	#endif
 	#endif
 EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`"
+	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
 	;;
-    or1k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+    mips64el:Linux:*:*)
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
-    or32:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-"$LIBC"
+	exit ;;
+    or32:Linux:*:* | or1k*:Linux:*:*)
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     padre:Linux:*:*)
-	echo sparc-unknown-linux-${LIBC}
+	echo sparc-unknown-linux-"$LIBC"
 	exit ;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-${LIBC}
+	echo hppa64-unknown-linux-"$LIBC"
 	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
-	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
-	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	  PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+	  PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+	  *)    echo hppa-unknown-linux-"$LIBC" ;;
 	esac
 	exit ;;
     ppc64:Linux:*:*)
-	echo powerpc64-unknown-linux-${LIBC}
+	echo powerpc64-unknown-linux-"$LIBC"
 	exit ;;
     ppc:Linux:*:*)
-	echo powerpc-unknown-linux-${LIBC}
+	echo powerpc-unknown-linux-"$LIBC"
 	exit ;;
     ppc64le:Linux:*:*)
-	echo powerpc64le-unknown-linux-${LIBC}
+	echo powerpc64le-unknown-linux-"$LIBC"
 	exit ;;
     ppcle:Linux:*:*)
-	echo powerpcle-unknown-linux-${LIBC}
+	echo powerpcle-unknown-linux-"$LIBC"
+	exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
 	exit ;;
     sh64*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     sh*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     tile*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     vax:Linux:*:*)
-	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
 	exit ;;
     x86_64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
 	exit ;;
     xtensa*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     i*86:DYNIX/ptx:4*:*)
 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1037,34 +1104,34 @@
 	# I am not positive that other SVR4 systems won't match this,
 	# I just have to hope.  -- rms.
 	# Use sysv4.2uw... so that sysv4* matches it.
-	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
 	exit ;;
     i*86:OS/2:*:*)
 	# If we were able to find `uname', then EMX Unix compatibility
 	# is probably installed.
-	echo ${UNAME_MACHINE}-pc-os2-emx
+	echo "$UNAME_MACHINE"-pc-os2-emx
 	exit ;;
     i*86:XTS-300:*:STOP)
-	echo ${UNAME_MACHINE}-unknown-stop
+	echo "$UNAME_MACHINE"-unknown-stop
 	exit ;;
     i*86:atheos:*:*)
-	echo ${UNAME_MACHINE}-unknown-atheos
+	echo "$UNAME_MACHINE"-unknown-atheos
 	exit ;;
     i*86:syllable:*:*)
-	echo ${UNAME_MACHINE}-pc-syllable
+	echo "$UNAME_MACHINE"-pc-syllable
 	exit ;;
     i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-	echo i386-unknown-lynxos${UNAME_RELEASE}
+	echo i386-unknown-lynxos"$UNAME_RELEASE"
 	exit ;;
     i*86:*DOS:*:*)
-	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	echo "$UNAME_MACHINE"-pc-msdosdjgpp
 	exit ;;
-    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
-	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+    i*86:*:4.*:*)
+	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+		echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
 	else
-		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+		echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
 	fi
 	exit ;;
     i*86:*:5:[678]*)
@@ -1074,12 +1141,12 @@
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
 	esac
-	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
 	exit ;;
     i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
 		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+		echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
 		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
 		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1089,9 +1156,9 @@
 			&& UNAME_MACHINE=i686
 		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
 			&& UNAME_MACHINE=i686
-		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+		echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
 	else
-		echo ${UNAME_MACHINE}-pc-sysv32
+		echo "$UNAME_MACHINE"-pc-sysv32
 	fi
 	exit ;;
     pc:*:*:*)
@@ -1099,7 +1166,7 @@
 	# uname -m prints for DJGPP always 'pc', but it prints nothing about
 	# the processor, so we play safe by assuming i586.
 	# Note: whatever this is, it MUST be the same as what config.sub
-	# prints for the "djgpp" host, or else GDB configury will decide that
+	# prints for the "djgpp" host, or else GDB configure will decide that
 	# this is a cross-build.
 	echo i586-pc-msdosdjgpp
 	exit ;;
@@ -1111,9 +1178,9 @@
 	exit ;;
     i860:*:4.*:*) # i860-SVR4
 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	  echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
 	else # Add other i860-SVR4 vendors below as they are discovered.
-	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	  echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4
 	fi
 	exit ;;
     mini*:CTIX:SYS*5:*)
@@ -1133,9 +1200,9 @@
 	test -r /etc/.relid \
 	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+	  && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 	  && { echo i486-ncr-sysv4; exit; } ;;
@@ -1144,28 +1211,28 @@
 	test -r /etc/.relid \
 	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
-	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	echo m68k-unknown-lynxos"$UNAME_RELEASE"
 	exit ;;
     mc68030:UNIX_System_V:4.*:*)
 	echo m68k-atari-sysv4
 	exit ;;
     TSUNAMI:LynxOS:2.*:*)
-	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	echo sparc-unknown-lynxos"$UNAME_RELEASE"
 	exit ;;
     rs6000:LynxOS:2.*:*)
-	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	echo rs6000-unknown-lynxos"$UNAME_RELEASE"
 	exit ;;
     PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	echo powerpc-unknown-lynxos"$UNAME_RELEASE"
 	exit ;;
     SM[BE]S:UNIX_SV:*:*)
-	echo mips-dde-sysv${UNAME_RELEASE}
+	echo mips-dde-sysv"$UNAME_RELEASE"
 	exit ;;
     RM*:ReliantUNIX-*:*:*)
 	echo mips-sni-sysv4
@@ -1176,7 +1243,7 @@
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
-		echo ${UNAME_MACHINE}-sni-sysv4
+		echo "$UNAME_MACHINE"-sni-sysv4
 	else
 		echo ns32k-sni-sysv
 	fi
@@ -1196,23 +1263,23 @@
 	exit ;;
     i*86:VOS:*:*)
 	# From [email protected].
-	echo ${UNAME_MACHINE}-stratus-vos
+	echo "$UNAME_MACHINE"-stratus-vos
 	exit ;;
     *:VOS:*:*)
 	# From [email protected].
 	echo hppa1.1-stratus-vos
 	exit ;;
     mc68*:A/UX:*:*)
-	echo m68k-apple-aux${UNAME_RELEASE}
+	echo m68k-apple-aux"$UNAME_RELEASE"
 	exit ;;
     news*:NEWS-OS:6*:*)
 	echo mips-sony-newsos6
 	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
 	if [ -d /usr/nec ]; then
-		echo mips-nec-sysv${UNAME_RELEASE}
+		echo mips-nec-sysv"$UNAME_RELEASE"
 	else
-		echo mips-unknown-sysv${UNAME_RELEASE}
+		echo mips-unknown-sysv"$UNAME_RELEASE"
 	fi
 	exit ;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
@@ -1231,67 +1298,93 @@
 	echo x86_64-unknown-haiku
 	exit ;;
     SX-4:SUPER-UX:*:*)
-	echo sx4-nec-superux${UNAME_RELEASE}
+	echo sx4-nec-superux"$UNAME_RELEASE"
 	exit ;;
     SX-5:SUPER-UX:*:*)
-	echo sx5-nec-superux${UNAME_RELEASE}
+	echo sx5-nec-superux"$UNAME_RELEASE"
 	exit ;;
     SX-6:SUPER-UX:*:*)
-	echo sx6-nec-superux${UNAME_RELEASE}
+	echo sx6-nec-superux"$UNAME_RELEASE"
 	exit ;;
     SX-7:SUPER-UX:*:*)
-	echo sx7-nec-superux${UNAME_RELEASE}
+	echo sx7-nec-superux"$UNAME_RELEASE"
 	exit ;;
     SX-8:SUPER-UX:*:*)
-	echo sx8-nec-superux${UNAME_RELEASE}
+	echo sx8-nec-superux"$UNAME_RELEASE"
 	exit ;;
     SX-8R:SUPER-UX:*:*)
-	echo sx8r-nec-superux${UNAME_RELEASE}
+	echo sx8r-nec-superux"$UNAME_RELEASE"
+	exit ;;
+    SX-ACE:SUPER-UX:*:*)
+	echo sxace-nec-superux"$UNAME_RELEASE"
 	exit ;;
     Power*:Rhapsody:*:*)
-	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	echo powerpc-apple-rhapsody"$UNAME_RELEASE"
 	exit ;;
     *:Rhapsody:*:*)
-	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
 	exit ;;
     *:Darwin:*:*)
 	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-	eval $set_cc_for_build
+	set_cc_for_build
 	if test "$UNAME_PROCESSOR" = unknown ; then
 	    UNAME_PROCESSOR=powerpc
 	fi
-	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		grep IS_64BIT_ARCH >/dev/null
-	    then
-		case $UNAME_PROCESSOR in
-		    i386) UNAME_PROCESSOR=x86_64 ;;
-		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		esac
+	if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		       grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
+		# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+		if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		       grep IS_PPC >/dev/null
+		then
+		    UNAME_PROCESSOR=powerpc
+		fi
 	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
 	fi
-	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
 	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
 	UNAME_PROCESSOR=`uname -p`
-	if test "$UNAME_PROCESSOR" = "x86"; then
+	if test "$UNAME_PROCESSOR" = x86; then
 		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
 	fi
-	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
 	exit ;;
     *:QNX:*:4*)
 	echo i386-pc-qnx
 	exit ;;
-    NEO-?:NONSTOP_KERNEL:*:*)
-	echo neo-tandem-nsk${UNAME_RELEASE}
+    NEO-*:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk"$UNAME_RELEASE"
 	exit ;;
     NSE-*:NONSTOP_KERNEL:*:*)
-	echo nse-tandem-nsk${UNAME_RELEASE}
+	echo nse-tandem-nsk"$UNAME_RELEASE"
+	exit ;;
+    NSR-*:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk"$UNAME_RELEASE"
 	exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
-	echo nsr-tandem-nsk${UNAME_RELEASE}
+    NSV-*:NONSTOP_KERNEL:*:*)
+	echo nsv-tandem-nsk"$UNAME_RELEASE"
+	exit ;;
+    NSX-*:NONSTOP_KERNEL:*:*)
+	echo nsx-tandem-nsk"$UNAME_RELEASE"
 	exit ;;
     *:NonStop-UX:*:*)
 	echo mips-compaq-nonstopux
@@ -1300,18 +1393,19 @@
 	echo bs2000-siemens-sysv
 	exit ;;
     DS/*:UNIX_System_V:*:*)
-	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
 	exit ;;
     *:Plan9:*:*)
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
 	# operating systems.
-	if test "$cputype" = "386"; then
+	# shellcheck disable=SC2154
+	if test "$cputype" = 386; then
 	    UNAME_MACHINE=i386
 	else
 	    UNAME_MACHINE="$cputype"
 	fi
-	echo ${UNAME_MACHINE}-unknown-plan9
+	echo "$UNAME_MACHINE"-unknown-plan9
 	exit ;;
     *:TOPS-10:*:*)
 	echo pdp10-unknown-tops10
@@ -1332,14 +1426,14 @@
 	echo pdp10-unknown-its
 	exit ;;
     SEI:*:*:SEIUX)
-	echo mips-sei-seiux${UNAME_RELEASE}
+	echo mips-sei-seiux"$UNAME_RELEASE"
 	exit ;;
     *:DragonFly:*:*)
-	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
 	exit ;;
     *:*VMS:*:*)
 	UNAME_MACHINE=`(uname -p) 2>/dev/null`
-	case "${UNAME_MACHINE}" in
+	case "$UNAME_MACHINE" in
 	    A*) echo alpha-dec-vms ; exit ;;
 	    I*) echo ia64-dec-vms ; exit ;;
 	    V*) echo vax-dec-vms ; exit ;;
@@ -1348,24 +1442,31 @@
 	echo i386-pc-xenix
 	exit ;;
     i*86:skyos:*:*)
-	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
 	exit ;;
     i*86:rdos:*:*)
-	echo ${UNAME_MACHINE}-pc-rdos
+	echo "$UNAME_MACHINE"-pc-rdos
 	exit ;;
     i*86:AROS:*:*)
-	echo ${UNAME_MACHINE}-pc-aros
+	echo "$UNAME_MACHINE"-pc-aros
 	exit ;;
     x86_64:VMkernel:*:*)
-	echo ${UNAME_MACHINE}-unknown-esx
+	echo "$UNAME_MACHINE"-unknown-esx
+	exit ;;
+    amd64:Isilon\ OneFS:*:*)
+	echo x86_64-unknown-onefs
+	exit ;;
+    *:Unleashed:*:*)
+	echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
 	exit ;;
 esac
 
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
+# No uname command or uname output not recognized.
+set_cc_for_build
+cat > "$dummy.c" <<EOF
 #ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
 #endif
 main ()
 {
@@ -1378,20 +1479,12 @@
 #include <sys/param.h>
   printf ("m68k-sony-newsos%s\n",
 #ifdef NEWSOS4
-	"4"
+  "4"
 #else
-	""
-#endif
-	); exit (0);
-#endif
+  ""
 #endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
+  ); exit (0);
 #endif
-
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
 #endif
 
 #if defined (NeXT)
@@ -1433,39 +1526,49 @@
 #endif
 
 #if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
+  struct utsname un;
 
-    if (strncmp(un.version, "V2", 2) == 0) {
-	printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-	printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
+  uname(&un);
+  if (strncmp(un.version, "V2", 2) == 0) {
+    printf ("i386-sequent-ptx2\n"); exit (0);
+  }
+  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+    printf ("i386-sequent-ptx1\n"); exit (0);
+  }
+  printf ("i386-sequent-ptx\n"); exit (0);
 #endif
 
 #if defined (vax)
-# if !defined (ultrix)
-#  include <sys/param.h>
-#  if defined (BSD)
-#   if BSD == 43
-      printf ("vax-dec-bsd4.3\n"); exit (0);
-#   else
-#    if BSD == 199006
-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
-#    else
-      printf ("vax-dec-bsd\n"); exit (0);
-#    endif
-#   endif
-#  else
-    printf ("vax-dec-bsd\n"); exit (0);
-#  endif
-# else
-    printf ("vax-dec-ultrix\n"); exit (0);
-# endif
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+  printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+  printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#include <signal.h>
+#if defined(_SIZE_T_) /* >= ULTRIX4 */
+  printf ("mips-dec-ultrix4\n"); exit (0);
+#else
+#if defined(ULTRIX3) || defined(ultrix3) || defined(SIGLOST)
+  printf ("mips-dec-ultrix3\n"); exit (0);
+#endif
+#endif
+#endif
 #endif
 
 #if defined (alliant) && defined (i860)
@@ -1476,54 +1579,38 @@
 }
 EOF
 
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` &&
 	{ echo "$SYSTEM_NAME"; exit; }
 
 # Apollos put the system type in the environment.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
 
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
+echo "$0: unable to guess system type" >&2
 
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-	echo c1-convex-bsd
-	exit ;;
-    c2*)
-	if getsysinfo -f scalar_acc
-	then echo c32-convex-bsd
-	else echo c2-convex-bsd
-	fi
-	exit ;;
-    c34*)
-	echo c34-convex-bsd
-	exit ;;
-    c38*)
-	echo c38-convex-bsd
-	exit ;;
-    c4*)
-	echo c4-convex-bsd
-	exit ;;
-    esac
-fi
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+    mips:Linux | mips64:Linux)
+	# If we got here on MIPS GNU/Linux, output extra information.
+	cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+	;;
+esac
 
 cat >&2 <<EOF
-$0: unable to guess system type
 
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
 
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <[email protected]> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to [email protected] to
+provide the necessary information to handle your system.
 
 config.guess timestamp = $timestamp
 
@@ -1542,16 +1629,16 @@
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
 
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM  = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM  = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
 EOF
 
 exit 1
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
--- a/config.sub	Thu Mar 21 23:28:59 2019 +0800
+++ b/config.sub	Fri Jun 26 21:07:34 2020 +0800
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2013 Free Software Foundation, Inc.
+#   Copyright 1992-2019 Free Software Foundation, Inc.
 
-timestamp='2013-10-01'
+timestamp='2019-01-05'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -25,7 +25,7 @@
 # of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches with a ChangeLog entry to [email protected].
+# Please send patches to <[email protected]>.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -33,7 +33,7 @@
 # Otherwise, we print the canonical config type on stdout and succeed.
 
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
@@ -53,12 +53,11 @@
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
 
 Canonicalize a configuration name.
 
-Operation modes:
+Options:
   -h, --help         print this help, then exit
   -t, --time-stamp   print date of last modification, then exit
   -v, --version      print version number, then exit
@@ -68,7 +67,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2019 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -90,12 +89,12 @@
     - )	# Use stdin as input.
        break ;;
     -* )
-       echo "$me: invalid option $1$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
 
     *local*)
        # First pass through any local machine types.
-       echo $1
+       echo "$1"
        exit ;;
 
     * )
@@ -111,1211 +110,1164 @@
     exit 1;;
 esac
 
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
 
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-	-sun*os*)
-		# Prevent following clause from handling this invalid input.
+# Separate into logical components for further validation
+case $1 in
+	*-*-*-*-*)
+		echo Invalid configuration \`"$1"\': more than four components >&2
+		exit 1
+		;;
+	*-*-*-*)
+		basic_machine=$field1-$field2
+		os=$field3-$field4
 		;;
-	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray | -microblaze*)
-		os=
-		basic_machine=$1
+	*-*-*)
+		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+		# parts
+		maybe_os=$field2-$field3
+		case $maybe_os in
+			nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
+			| linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+			| storm-chaos* | os2-emx* | rtmk-nova*)
+				basic_machine=$field1
+				os=$maybe_os
+				;;
+			android-linux)
+				basic_machine=$field1-unknown
+				os=linux-android
+				;;
+			*)
+				basic_machine=$field1-$field2
+				os=$field3
+				;;
+		esac
 		;;
-	-bluegene*)
-		os=-cnk
-		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
-		;;
-	-scout)
-		;;
-	-wrs)
-		os=-vxworks
-		basic_machine=$1
-		;;
-	-chorusos*)
-		os=-chorusos
-		basic_machine=$1
-		;;
-	-chorusrdb)
-		os=-chorusrdb
-		basic_machine=$1
+	*-*)
+		# A lone config we happen to match not fitting any pattern
+		case $field1-$field2 in
+			decstation-3100)
+				basic_machine=mips-dec
+				os=
+				;;
+			*-*)
+				# Second component is usually, but not always the OS
+				case $field2 in
+					# Prevent following clause from handling this valid os
+					sun*os*)
+						basic_machine=$field1
+						os=$field2
+						;;
+					# Manufacturers
+					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
+					| convergent* | ncr* | news | 32* | 3600* | 3100* \
+					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+					| ultra | tti* | harris | dolphin | highlevel | gould \
+					| cbm | ns | masscomp | apple | axis | knuth | cray \
+					| microblaze* | sim | cisco \
+					| oki | wec | wrs | winbond)
+						basic_machine=$field1-$field2
+						os=
+						;;
+					*)
+						basic_machine=$field1
+						os=$field2
+						;;
+				esac
+			;;
+		esac
 		;;
-	-hiux*)
-		os=-hiuxwe2
-		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5)
-		os=-sco3.2v5
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco4)
-		os=-sco3.2v4
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2.[4-9]*)
-		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2v[4-9]*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco*)
-		os=-sco3.2v2
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-udk*)
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-isc)
-		os=-isc2.2
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-clix*)
-		basic_machine=clipper-intergraph
-		;;
-	-isc*)
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
-	-lynx*178)
-		os=-lynxos178
-		;;
-	-lynx*5)
-		os=-lynxos5
-		;;
-	-lynx*)
-		os=-lynxos
-		;;
-	-ptx*)
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-		;;
-	-windowsnt*)
-		os=`echo $os | sed -e 's/windowsnt/winnt/'`
-		;;
-	-psos*)
-		os=-psos
-		;;
-	-mint | -mint[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
+	*)
+		# Convert single-component short-hands not valid as part of
+		# multi-component configurations.
+		case $field1 in
+			386bsd)
+				basic_machine=i386-pc
+				os=bsd
+				;;
+			a29khif)
+				basic_machine=a29k-amd
+				os=udi
+				;;
+			adobe68k)
+				basic_machine=m68010-adobe
+				os=scout
+				;;
+			alliant)
+				basic_machine=fx80-alliant
+				os=
+				;;
+			altos | altos3068)
+				basic_machine=m68k-altos
+				os=
+				;;
+			am29k)
+				basic_machine=a29k-none
+				os=bsd
+				;;
+			amdahl)
+				basic_machine=580-amdahl
+				os=sysv
+				;;
+			amiga)
+				basic_machine=m68k-unknown
+				os=
+				;;
+			amigaos | amigados)
+				basic_machine=m68k-unknown
+				os=amigaos
+				;;
+			amigaunix | amix)
+				basic_machine=m68k-unknown
+				os=sysv4
+				;;
+			apollo68)
+				basic_machine=m68k-apollo
+				os=sysv
+				;;
+			apollo68bsd)
+				basic_machine=m68k-apollo
+				os=bsd
+				;;
+			aros)
+				basic_machine=i386-pc
+				os=aros
+				;;
+			aux)
+				basic_machine=m68k-apple
+				os=aux
+				;;
+			balance)
+				basic_machine=ns32k-sequent
+				os=dynix
+				;;
+			blackfin)
+				basic_machine=bfin-unknown
+				os=linux
+				;;
+			cegcc)
+				basic_machine=arm-unknown
+				os=cegcc
+				;;
+			convex-c1)
+				basic_machine=c1-convex
+				os=bsd
+				;;
+			convex-c2)
+				basic_machine=c2-convex
+				os=bsd
+				;;
+			convex-c32)
+				basic_machine=c32-convex
+				os=bsd
+				;;
+			convex-c34)
+				basic_machine=c34-convex
+				os=bsd
+				;;
+			convex-c38)
+				basic_machine=c38-convex
+				os=bsd
+				;;
+			cray)
+				basic_machine=j90-cray
+				os=unicos
+				;;
+			crds | unos)
+				basic_machine=m68k-crds
+				os=
+				;;
+			da30)
+				basic_machine=m68k-da30
+				os=
+				;;
+			decstation | pmax | pmin | dec3100 | decstatn)
+				basic_machine=mips-dec
+				os=
+				;;
+			delta88)
+				basic_machine=m88k-motorola
+				os=sysv3
+				;;
+			dicos)
+				basic_machine=i686-pc
+				os=dicos
+				;;
+			djgpp)
+				basic_machine=i586-pc
+				os=msdosdjgpp
+				;;
+			ebmon29k)
+				basic_machine=a29k-amd
+				os=ebmon
+				;;
+			es1800 | OSE68k | ose68k | ose | OSE)
+				basic_machine=m68k-ericsson
+				os=ose
+				;;
+			gmicro)
+				basic_machine=tron-gmicro
+				os=sysv
+				;;
+			go32)
+				basic_machine=i386-pc
+				os=go32
+				;;
+			h8300hms)
+				basic_machine=h8300-hitachi
+				os=hms
+				;;
+			h8300xray)
+				basic_machine=h8300-hitachi
+				os=xray
+				;;
+			h8500hms)
+				basic_machine=h8500-hitachi
+				os=hms
+				;;
+			harris)
+				basic_machine=m88k-harris
+				os=sysv3
+				;;
+			hp300)
+				basic_machine=m68k-hp
+				;;
+			hp300bsd)
+				basic_machine=m68k-hp
+				os=bsd
+				;;
+			hp300hpux)
+				basic_machine=m68k-hp
+				os=hpux
+				;;
+			hppaosf)
+				basic_machine=hppa1.1-hp
+				os=osf
+				;;
+			hppro)
+				basic_machine=hppa1.1-hp
+				os=proelf
+				;;
+			i386mach)
+				basic_machine=i386-mach
+				os=mach
+				;;
+			vsta)
+				basic_machine=i386-pc
+				os=vsta
+				;;
+			isi68 | isi)
+				basic_machine=m68k-isi
+				os=sysv
+				;;
+			m68knommu)
+				basic_machine=m68k-unknown
+				os=linux
+				;;
+			magnum | m3230)
+				basic_machine=mips-mips
+				os=sysv
+				;;
+			merlin)
+				basic_machine=ns32k-utek
+				os=sysv
+				;;
+			mingw64)
+				basic_machine=x86_64-pc
+				os=mingw64
+				;;
+			mingw32)
+				basic_machine=i686-pc
+				os=mingw32
+				;;
+			mingw32ce)
+				basic_machine=arm-unknown
+				os=mingw32ce
+				;;
+			monitor)
+				basic_machine=m68k-rom68k
+				os=coff
+				;;
+			morphos)
+				basic_machine=powerpc-unknown
+				os=morphos
+				;;
+			moxiebox)
+				basic_machine=moxie-unknown
+				os=moxiebox
+				;;
+			msdos)
+				basic_machine=i386-pc
+				os=msdos
+				;;
+			msys)
+				basic_machine=i686-pc
+				os=msys
+				;;
+			mvs)
+				basic_machine=i370-ibm
+				os=mvs
+				;;
+			nacl)
+				basic_machine=le32-unknown
+				os=nacl
+				;;
+			ncr3000)
+				basic_machine=i486-ncr
+				os=sysv4
+				;;
+			netbsd386)
+				basic_machine=i386-pc
+				os=netbsd
+				;;
+			netwinder)
+				basic_machine=armv4l-rebel
+				os=linux
+				;;
+			news | news700 | news800 | news900)
+				basic_machine=m68k-sony
+				os=newsos
+				;;
+			news1000)
+				basic_machine=m68030-sony
+				os=newsos
+				;;
+			necv70)
+				basic_machine=v70-nec
+				os=sysv
+				;;
+			nh3000)
+				basic_machine=m68k-harris
+				os=cxux
+				;;
+			nh[45]000)
+				basic_machine=m88k-harris
+				os=cxux
+				;;
+			nindy960)
+				basic_machine=i960-intel
+				os=nindy
+				;;
+			mon960)
+				basic_machine=i960-intel
+				os=mon960
+				;;
+			nonstopux)
+				basic_machine=mips-compaq
+				os=nonstopux
+				;;
+			os400)
+				basic_machine=powerpc-ibm
+				os=os400
+				;;
+			OSE68000 | ose68000)
+				basic_machine=m68000-ericsson
+				os=ose
+				;;
+			os68k)
+				basic_machine=m68k-none
+				os=os68k
+				;;
+			paragon)
+				basic_machine=i860-intel
+				os=osf
+				;;
+			parisc)
+				basic_machine=hppa-unknown
+				os=linux
+				;;
+			pw32)
+				basic_machine=i586-unknown
+				os=pw32
+				;;
+			rdos | rdos64)
+				basic_machine=x86_64-pc
+				os=rdos
+				;;
+			rdos32)
+				basic_machine=i386-pc
+				os=rdos
+				;;
+			rom68k)
+				basic_machine=m68k-rom68k
+				os=coff
+				;;
+			sa29200)
+				basic_machine=a29k-amd
+				os=udi
+				;;
+			sei)
+				basic_machine=mips-sei
+				os=seiux
+				;;
+			sequent)
+				basic_machine=i386-sequent
+				os=
+				;;
+			sps7)
+				basic_machine=m68k-bull
+				os=sysv2
+				;;
+			st2000)
+				basic_machine=m68k-tandem
+				os=
+				;;
+			stratus)
+				basic_machine=i860-stratus
+				os=sysv4
+				;;
+			sun2)
+				basic_machine=m68000-sun
+				os=
+				;;
+			sun2os3)
+				basic_machine=m68000-sun
+				os=sunos3
+				;;
+			sun2os4)
+				basic_machine=m68000-sun
+				os=sunos4
+				;;
+			sun3)
+				basic_machine=m68k-sun
+				os=
+				;;
+			sun3os3)
+				basic_machine=m68k-sun
+				os=sunos3
+				;;
+			sun3os4)
+				basic_machine=m68k-sun
+				os=sunos4
+				;;
+			sun4)
+				basic_machine=sparc-sun
+				os=
+				;;
+			sun4os3)
+				basic_machine=sparc-sun
+				os=sunos3
+				;;
+			sun4os4)
+				basic_machine=sparc-sun
+				os=sunos4
+				;;
+			sun4sol2)
+				basic_machine=sparc-sun
+				os=solaris2
+				;;
+			sun386 | sun386i | roadrunner)
+				basic_machine=i386-sun
+				os=
+				;;
+			sv1)
+				basic_machine=sv1-cray
+				os=unicos
+				;;
+			symmetry)
+				basic_machine=i386-sequent
+				os=dynix
+				;;
+			t3e)
+				basic_machine=alphaev5-cray
+				os=unicos
+				;;
+			t90)
+				basic_machine=t90-cray
+				os=unicos
+				;;
+			toad1)
+				basic_machine=pdp10-xkl
+				os=tops20
+				;;
+			tpf)
+				basic_machine=s390x-ibm
+				os=tpf
+				;;
+			udi29k)
+				basic_machine=a29k-amd
+				os=udi
+				;;
+			ultra3)
+				basic_machine=a29k-nyu
+				os=sym1
+				;;
+			v810 | necv810)
+				basic_machine=v810-nec
+				os=none
+				;;
+			vaxv)
+				basic_machine=vax-dec
+				os=sysv
+				;;
+			vms)
+				basic_machine=vax-dec
+				os=vms
+				;;
+			vxworks960)
+				basic_machine=i960-wrs
+				os=vxworks
+				;;
+			vxworks68)
+				basic_machine=m68k-wrs
+				os=vxworks
+				;;
+			vxworks29k)
+				basic_machine=a29k-wrs
+				os=vxworks
+				;;
+			xbox)
+				basic_machine=i686-pc
+				os=mingw32
+				;;
+			ymp)
+				basic_machine=ymp-cray
+				os=unicos
+				;;
+			*)
+				basic_machine=$1
+				os=
+				;;
+		esac
 		;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
-	# Recognize the basic CPU types without company name.
-	# Some are omitted here because they have special meanings below.
-	1750a | 580 \
-	| a29k \
-	| aarch64 | aarch64_be \
-	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arceb \
-	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-	| avr | avr32 \
-	| be32 | be64 \
-	| bfin \
-	| c4x | c8051 | clipper \
-	| d10v | d30v | dlx | dsp16xx \
-	| epiphany \
-	| fido | fr30 | frv \
-	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-	| hexagon \
-	| i370 | i860 | i960 | ia64 \
-	| ip2k | iq2000 \
-	| k1om \
-	| le32 | le64 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-	| mips | mipsbe | mipseb | mipsel | mipsle \
-	| mips16 \
-	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
-	| mips64vr | mips64vrel \
-	| mips64vr4100 | mips64vr4100el \
-	| mips64vr4300 | mips64vr4300el \
-	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
-	| mipsisa32 | mipsisa32el \
-	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64sb1 | mipsisa64sb1el \
-	| mipsisa64sr71k | mipsisa64sr71kel \
-	| mipsr5900 | mipsr5900el \
-	| mipstx39 | mipstx39el \
-	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
-	| msp430 \
-	| nds32 | nds32le | nds32be \
-	| nios | nios2 | nios2eb | nios2el \
-	| ns16k | ns32k \
-	| open8 \
-	| or1k | or32 \
-	| pdp10 | pdp11 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle \
-	| pyramid \
-	| rl78 | rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu \
-	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-	| ubicom32 \
-	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| we32k \
-	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
-		basic_machine=$basic_machine-unknown
+	# Here we handle the default manufacturer of certain CPU types.  It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		cpu=hppa1.1
+		vendor=winbond
+		;;
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
+		;;
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c54x)
-		basic_machine=tic54x-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
 		;;
-	c55x)
-		basic_machine=tic55x-unknown
-		;;
-	c6x)
-		basic_machine=tic6x-unknown
+	orion105)
+		cpu=clipper
+		vendor=highlevel
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
 		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
-		;;
-	ms1)
-		basic_machine=mt-unknown
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
 		;;
 
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		cpu=m68000
+		vendor=att
+		;;
+	3b*)
+		cpu=we32k
+		vendor=att
+		;;
+	bluegene*)
+		cpu=powerpc
+		vendor=ibm
+		os=cnk
+		;;
+	decsystem10* | dec10*)
+		cpu=pdp10
+		vendor=dec
+		os=tops10
+		;;
+	decsystem20* | dec20*)
+		cpu=pdp10
+		vendor=dec
+		os=tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		cpu=m68k
+		vendor=motorola
+		;;
+	dpx2*)
+		cpu=m68k
+		vendor=bull
+		os=sysv3
+		;;
+	encore | umax | mmax)
+		cpu=ns32k
+		vendor=encore
+		;;
+	elxsi)
+		cpu=elxsi
+		vendor=elxsi
+		os=${os:-bsd}
+		;;
+	fx2800)
+		cpu=i860
+		vendor=alliant
+		;;
+	genix)
+		cpu=ns32k
+		vendor=ns
+		;;
+	h3050r* | hiux*)
+		cpu=hppa1.1
+		vendor=hitachi
+		os=hiuxwe2
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		cpu=m68000
+		vendor=hp
+		;;
+	hp9k3[2-9][0-9])
+		cpu=m68k
+		vendor=hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	i*86v32)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=sysv32
+		;;
+	i*86v4*)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=sysv4
+		;;
+	i*86v)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=sysv
+		;;
+	i*86sol2)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=solaris2
+		;;
+	j90 | j90-cray)
+		cpu=j90
+		vendor=cray
+		os=${os:-unicos}
 		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
+	iris | iris4d)
+		cpu=mips
+		vendor=sgi
+		case $os in
+		    irix*)
+			;;
+		    *)
+			os=irix4
+			;;
+		esac
+		;;
+	miniframe)
+		cpu=m68000
+		vendor=convergent
+		;;
+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		cpu=m68k
+		vendor=atari
+		os=mint
+		;;
+	news-3600 | risc-news)
+		cpu=mips
+		vendor=sony
+		os=newsos
+		;;
+	next | m*-next)
+		cpu=m68k
+		vendor=next
+		case $os in
+		    nextstep* )
+			;;
+		    ns2*)
+		      os=nextstep2
+			;;
+		    *)
+		      os=nextstep3
+			;;
+		esac
+		;;
+	np1)
+		cpu=np1
+		vendor=gould
+		;;
+	op50n-* | op60c-*)
+		cpu=hppa1.1
+		vendor=oki
+		os=proelf
+		;;
+	pa-hitachi)
+		cpu=hppa1.1
+		vendor=hitachi
+		os=hiuxwe2
+		;;
+	pbd)
+		cpu=sparc
+		vendor=tti
+		;;
+	pbb)
+		cpu=m68k
+		vendor=tti
 		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
+	pc532)
+		cpu=ns32k
+		vendor=pc532
+		;;
+	pn)
+		cpu=pn
+		vendor=gould
+		;;
+	power)
+		cpu=power
+		vendor=ibm
+		;;
+	ps2)
+		cpu=i386
+		vendor=ibm
+		;;
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
+		;;
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
+		;;
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		os=${os:-elf}
+		;;
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		os=vxworks
+		;;
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
+		;;
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
+		;;
+	w65)
+		cpu=w65
+		vendor=wdc
+		;;
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		os=proelf
+		;;
+	none)
+		cpu=none
+		vendor=none
+		;;
+	leon|leon[3-9])
+		cpu=sparc
+		vendor=$basic_machine
+		;;
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=`echo "$basic_machine" | sed 's/-.*//'`
 		;;
 
-	xscaleel)
-		basic_machine=armel-unknown
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
 		;;
-
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
 	# (2) the word "unknown" tends to confuse beginning users.
 	i*86 | x86_64)
-	  basic_machine=$basic_machine-pc
-	  ;;
-	# Object if more than one company name word.
-	*-*-*)
-		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-		exit 1
+		cpu=$basic_machine
+		vendor=pc
+		;;
+	# These rules are duplicated from below for sake of the special case above;
+	# i.e. things that normalized to x86 arches should also default to "pc"
+	pc98)
+		cpu=i386
+		vendor=pc
+		;;
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
+		;;
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
+		;;
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	craynv-unknown)
+		vendor=cray
+		os=${os:-unicosmp}
+		;;
+	c90-unknown | c90-cray)
+		vendor=cray
+		os=${os:-unicos}
+		;;
+	fx80-unknown)
+		vendor=alliant
+		;;
+	romp-unknown)
+		vendor=ibm
 		;;
-	# Recognize the basic CPU types with company name.
-	580-* \
-	| a29k-* \
-	| aarch64-* | aarch64_be-* \
-	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| be32-* | be64-* \
-	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* \
-	| c8051-* | clipper-* | craynv-* | cydra-* \
-	| d10v-* | d30v-* | dlx-* \
-	| elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-	| h8300-* | h8500-* \
-	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| k1om-* \
-	| le32-* | le64-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
-	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-	| microblaze-* | microblazeel-* \
-	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-	| mips16-* \
-	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
-	| mips64vr-* | mips64vrel-* \
-	| mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* \
-	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
-	| mipsisa32-* | mipsisa32el-* \
-	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64sb1-* | mipsisa64sb1el-* \
-	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
-	| mipsr5900-* | mipsr5900el-* \
-	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
-	| msp430-* \
-	| nds32-* | nds32le-* | nds32be-* \
-	| nios-* | nios2-* | nios2eb-* | nios2el-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
-	| open8-* \
-	| orion-* \
-	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-	| pyramid-* \
-	| rl78-* | romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
-	| tahoe-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-	| tile*-* \
-	| tron-* \
-	| ubicom32-* \
-	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-	| vax-* \
-	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* \
-	| xstormy16-* | xtensa*-* \
-	| ymp-* \
-	| z8k-* | z80-*)
+	mmix-unknown)
+		vendor=knuth
+		;;
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
+		;;
+	rs6000-unknown)
+		vendor=ibm
+		;;
+	vax-unknown)
+		vendor=dec
+		;;
+	pdp11-unknown)
+		vendor=dec
+		;;
+	we32k-unknown)
+		vendor=att
+		;;
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
-		;;
-	# Recognize the various machine names and aliases which stand
-	# for a CPU type and a company and sometimes even an OS.
-	386bsd)
-		basic_machine=i386-unknown
-		os=-bsd
+	i370-ibm*)
+		vendor=ibm
 		;;
-	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-		basic_machine=m68000-att
+	orion-unknown)
+		vendor=highlevel
 		;;
-	3b*)
-		basic_machine=we32k-att
-		;;
-	a29khif)
-		basic_machine=a29k-amd
-		os=-udi
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
 		;;
-	abacus)
-		basic_machine=abacus-unknown
-		;;
-	adobe68k)
-		basic_machine=m68010-adobe
-		os=-scout
-		;;
-	alliant | fx80)
-		basic_machine=fx80-alliant
+
+	# Here we normalize CPU types with a missing or matching vendor
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		os=${os:-bosx}
 		;;
-	altos | altos3068)
-		basic_machine=m68k-altos
-		;;
-	am29k)
-		basic_machine=a29k-none
-		os=-bsd
-		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
+
+	# Here we normalize CPU types irrespective of the vendor
 	amd64-*)
-		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	amdahl)
-		basic_machine=580-amdahl
-		os=-sysv
-		;;
-	amiga | amiga-*)
-		basic_machine=m68k-unknown
-		;;
-	amigaos | amigados)
-		basic_machine=m68k-unknown
-		os=-amigaos
-		;;
-	amigaunix | amix)
-		basic_machine=m68k-unknown
-		os=-sysv4
-		;;
-	apollo68)
-		basic_machine=m68k-apollo
-		os=-sysv
-		;;
-	apollo68bsd)
-		basic_machine=m68k-apollo
-		os=-bsd
-		;;
-	aros)
-		basic_machine=i386-pc
-		os=-aros
-		;;
-	aux)
-		basic_machine=m68k-apple
-		os=-aux
-		;;
-	balance)
-		basic_machine=ns32k-sequent
-		os=-dynix
-		;;
-	blackfin)
-		basic_machine=bfin-unknown
-		os=-linux
+		cpu=x86_64
 		;;
 	blackfin-*)
-		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	bluegene*)
-		basic_machine=powerpc-ibm
-		os=-cnk
+		cpu=bfin
+		os=linux
 		;;
 	c54x-*)
-		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		cpu=tic54x
 		;;
 	c55x-*)
-		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		cpu=tic55x
 		;;
 	c6x-*)
-		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	c90)
-		basic_machine=c90-cray
-		os=-unicos
-		;;
-	cegcc)
-		basic_machine=arm-unknown
-		os=-cegcc
-		;;
-	convex-c1)
-		basic_machine=c1-convex
-		os=-bsd
-		;;
-	convex-c2)
-		basic_machine=c2-convex
-		os=-bsd
-		;;
-	convex-c32)
-		basic_machine=c32-convex
-		os=-bsd
-		;;
-	convex-c34)
-		basic_machine=c34-convex
-		os=-bsd
-		;;
-	convex-c38)
-		basic_machine=c38-convex
-		os=-bsd
-		;;
-	cray | j90)
-		basic_machine=j90-cray
-		os=-unicos
-		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16 | cr16-*)
-		basic_machine=cr16-unknown
-		os=-elf
-		;;
-	crds | unos)
-		basic_machine=m68k-crds
-		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
-	cris | cris-* | etrax*)
-		basic_machine=cris-axis
-		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
-	da30 | da30-*)
-		basic_machine=m68k-da30
-		;;
-	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-		basic_machine=mips-dec
-		;;
-	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
-		;;
-	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
-		;;
-	delta | 3300 | motorola-3300 | motorola-delta \
-	      | 3300-motorola | delta-motorola)
-		basic_machine=m68k-motorola
-		;;
-	delta88)
-		basic_machine=m88k-motorola
-		os=-sysv3
-		;;
-	dicos)
-		basic_machine=i686-pc
-		os=-dicos
-		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
-	dpx20 | dpx20-*)
-		basic_machine=rs6000-bull
-		os=-bosx
-		;;
-	dpx2* | dpx2*-bull)
-		basic_machine=m68k-bull
-		os=-sysv3
-		;;
-	ebmon29k)
-		basic_machine=a29k-amd
-		os=-ebmon
-		;;
-	elxsi)
-		basic_machine=elxsi-elxsi
-		os=-bsd
-		;;
-	encore | umax | mmax)
-		basic_machine=ns32k-encore
-		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
-		;;
-	fx2800)
-		basic_machine=i860-alliant
-		;;
-	genix)
-		basic_machine=ns32k-ns
-		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
-		;;
-	h3050r* | hiux*)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	h8300hms)
-		basic_machine=h8300-hitachi
-		os=-hms
-		;;
-	h8300xray)
-		basic_machine=h8300-hitachi
-		os=-xray
+		cpu=tic6x
 		;;
-	h8500hms)
-		basic_machine=h8500-hitachi
-		os=-hms
-		;;
-	harris)
-		basic_machine=m88k-harris
-		os=-sysv3
-		;;
-	hp300-*)
-		basic_machine=m68k-hp
-		;;
-	hp300bsd)
-		basic_machine=m68k-hp
-		os=-bsd
-		;;
-	hp300hpux)
-		basic_machine=m68k-hp
-		os=-hpux
-		;;
-	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
-		;;
-	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
-		;;
-	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k78[0-9] | hp78[0-9])
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][0-9] | hp8[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hppa-next)
-		os=-nextstep3
-		;;
-	hppaosf)
-		basic_machine=hppa1.1-hp
-		os=-osf
-		;;
-	hppro)
-		basic_machine=hppa1.1-hp
-		os=-proelf
-		;;
-	i370-ibm* | ibm*)
-		basic_machine=i370-ibm
-		;;
-	i*86v32)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
-		;;
-	i*86v4*)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
-		;;
-	i*86v)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-sysv
-		;;
-	i*86sol2)
-		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
-		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
-		;;
-	i386-vsta | vsta)
-		basic_machine=i386-unknown
-		os=-vsta
-		;;
-	iris | iris4d)
-		basic_machine=mips-sgi
-		case $os in
-		    -irix*)
-			;;
-		    *)
-			os=-irix4
-			;;
-		esac
-		;;
-	isi68 | isi)
-		basic_machine=m68k-isi
-		os=-sysv
-		;;
-	m68knommu)
-		basic_machine=m68k-unknown
-		os=-linux
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	m88k-omron*)
-		basic_machine=m88k-omron
-		;;
-	magnum | m3230)
-		basic_machine=mips-mips
-		os=-sysv
-		;;
-	merlin)
-		basic_machine=ns32k-utek
-		os=-sysv
-		;;
-	microblaze*)
-		basic_machine=microblaze-xilinx
-		;;
-	mingw64)
-		basic_machine=x86_64-pc
-		os=-mingw64
-		;;
-	mingw32)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	mingw32ce)
-		basic_machine=arm-unknown
-		os=-mingw32ce
-		;;
-	miniframe)
-		basic_machine=m68000-convergent
-		;;
-	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
+	e500v[12]-*)
+		cpu=powerpc
+		os=$os"spe"
 		;;
 	mips3*-*)
-		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
-		;;
-	mips3*)
-		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
-		;;
-	monitor)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	morphos)
-		basic_machine=powerpc-unknown
-		os=-morphos
-		;;
-	msdos)
-		basic_machine=i386-pc
-		os=-msdos
+		cpu=mips64
 		;;
 	ms1-*)
-		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-		;;
-	msys)
-		basic_machine=i686-pc
-		os=-msys
-		;;
-	mvs)
-		basic_machine=i370-ibm
-		os=-mvs
-		;;
-	nacl)
-		basic_machine=le32-unknown
-		os=-nacl
-		;;
-	ncr3000)
-		basic_machine=i486-ncr
-		os=-sysv4
-		;;
-	netbsd386)
-		basic_machine=i386-unknown
-		os=-netbsd
-		;;
-	netwinder)
-		basic_machine=armv4l-rebel
-		os=-linux
+		cpu=mt
 		;;
-	news | news700 | news800 | news900)
-		basic_machine=m68k-sony
-		os=-newsos
-		;;
-	news1000)
-		basic_machine=m68030-sony
-		os=-newsos
-		;;
-	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
-		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
-		;;
-	next | m*-next )
-		basic_machine=m68k-next
-		case $os in
-		    -nextstep* )
-			;;
-		    -ns2*)
-		      os=-nextstep2
-			;;
-		    *)
-		      os=-nextstep3
-			;;
-		esac
-		;;
-	nh3000)
-		basic_machine=m68k-harris
-		os=-cxux
+	m68knommu-*)
+		cpu=m68k
+		os=linux
 		;;
-	nh[45]000)
-		basic_machine=m88k-harris
-		os=-cxux
-		;;
-	nindy960)
-		basic_machine=i960-intel
-		os=-nindy
-		;;
-	mon960)
-		basic_machine=i960-intel
-		os=-mon960
-		;;
-	nonstopux)
-		basic_machine=mips-compaq
-		os=-nonstopux
-		;;
-	np1)
-		basic_machine=np1-gould
-		;;
-	neo-tandem)
-		basic_machine=neo-tandem
-		;;
-	nse-tandem)
-		basic_machine=nse-tandem
-		;;
-	nsr-tandem)
-		basic_machine=nsr-tandem
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	op50n-* | op60c-*)
-		basic_machine=hppa1.1-oki
-		os=-proelf
-		;;
-	openrisc | openrisc-*)
-		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
-		;;
-	OSE68000 | ose68000)
-		basic_machine=m68000-ericsson
-		os=-ose
-		;;
-	os68k)
-		basic_machine=m68k-none
-		os=-os68k
-		;;
-	pa-hitachi)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	paragon)
-		basic_machine=i860-intel
-		os=-osf
-		;;
-	parisc)
-		basic_machine=hppa-unknown
-		os=-linux
+	openrisc-*)
+		cpu=or32
 		;;
 	parisc-*)
-		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	pbd)
-		basic_machine=sparc-tti
-		;;
-	pbb)
-		basic_machine=m68k-tti
-		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
-		;;
-	pc98)
-		basic_machine=i386-pc
-		;;
-	pc98-*)
-		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
-		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
-		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
-		;;
-	pentium4)
-		basic_machine=i786-pc
+		cpu=hppa
+		os=linux
 		;;
 	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		cpu=i586
 		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
 	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		cpu=i686
 		;;
 	pentium4-*)
-		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		cpu=i786
 		;;
-	pn)
-		basic_machine=pn-gould
-		;;
-	power)	basic_machine=power-ibm
-		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
+	pc98-*)
+		cpu=i386
 		;;
 	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ppcle | powerpclittle | ppc-le | powerpc-little)
-		basic_machine=powerpcle-unknown
+		cpu=powerpc
 		;;
 	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ppc64)	basic_machine=powerpc64-unknown
+		cpu=powerpcle
 		;;
-	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
-		basic_machine=powerpc64le-unknown
+	ppc64-*)
+		cpu=powerpc64
 		;;
 	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	ps2)
-		basic_machine=i386-ibm
-		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
-		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
-		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
+		cpu=powerpc64le
 		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	rm[46]00)
-		basic_machine=mips-siemens
-		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
-		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
-		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
-		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
+	sb1-*)
+		cpu=mipsisa64sb1
 		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
-		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
-		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
-		;;
-	sequent)
-		basic_machine=i386-sequent
-		;;
-	sh)
-		basic_machine=sh-hitachi
-		os=-hms
-		;;
-	sh5el)
-		basic_machine=sh5le-unknown
+	sb1el-*)
+		cpu=mipsisa64sb1el
 		;;
-	sh64)
-		basic_machine=sh64-unknown
-		;;
-	sparclite-wrs | simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
+	sh5e[lb]-*)
+		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
 		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
-		;;
-	spur)
-		basic_machine=spur-unknown
-		;;
-	st2000)
-		basic_machine=m68k-tandem
-		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
+	spur-*)
+		cpu=spur
 		;;
 	strongarm-* | thumb-*)
-		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
-	sun2)
-		basic_machine=m68000-sun
-		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
-		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
-		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
-		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
-		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
-		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
+		cpu=arm
 		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
-		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
-		;;
-	sun4)
-		basic_machine=sparc-sun
-		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
-		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
-		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
-		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
-		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
-		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
+	tx39-*)
+		cpu=mipstx39
 		;;
-	tx39)
-		basic_machine=mipstx39-unknown
-		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
-		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
-		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
-		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
-		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
-		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
-		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
+	tx39el-*)
+		cpu=mipstx39el
 		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
-		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
-		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
-		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
-		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
-		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
-		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
-		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
+	x64-*)
+		cpu=x86_64
 		;;
 	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
+		;;
+
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		os=${os:-elf}
 		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
+		;;
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
+		;;
+	crx-*)
+		os=${os:-elf}
+		;;
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
 		;;
-	z8k-*-coff)
-		basic_machine=z8k-unknown
-		os=-sim
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
+		;;
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
+		;;
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
 		;;
-	z80-*-coff)
-		basic_machine=z80-unknown
-		os=-sim
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
 		;;
-	none)
-		basic_machine=none-none
-		os=-none
+	s390-*)
+		cpu=s390
+		vendor=ibm
+		;;
+	s390x-*)
+		cpu=s390x
+		vendor=ibm
+		;;
+	tile*-*)
+		os=${os:-linux-gnu}
 		;;
 
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-	w89k)
-		basic_machine=hppa1.1-winbond
-		;;
-	op50n)
-		basic_machine=hppa1.1-oki
-		;;
-	op60c)
-		basic_machine=hppa1.1-oki
-		;;
-	romp)
-		basic_machine=romp-ibm
-		;;
-	mmix)
-		basic_machine=mmix-knuth
-		;;
-	rs6000)
-		basic_machine=rs6000-ibm
-		;;
-	vax)
-		basic_machine=vax-dec
-		;;
-	pdp10)
-		# there are many clones, so DEC is not a safe bet
-		basic_machine=pdp10-unknown
-		;;
-	pdp11)
-		basic_machine=pdp11-dec
-		;;
-	we32k)
-		basic_machine=we32k-att
-		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
-		;;
-	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-		basic_machine=sparc-sun
-		;;
-	cydra)
-		basic_machine=cydra-cydrome
-		;;
-	orion)
-		basic_machine=orion-highlevel
-		;;
-	orion105)
-		basic_machine=clipper-highlevel
-		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
-		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
-		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
-		;;
 	*)
-		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-		exit 1
+		# Recognize the canonical CPU types that are allowed with any
+		# company name.
+		case $cpu in
+			1750a | 580 \
+			| a29k \
+			| aarch64 | aarch64_be \
+			| abacus \
+			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+			| alphapca5[67] | alpha64pca5[67] \
+			| am33_2.0 \
+			| amdgcn \
+			| arc | arceb \
+			| arm  | arm[lb]e | arme[lb] | armv* \
+			| avr | avr32 \
+			| asmjs \
+			| ba \
+			| be32 | be64 \
+			| bfin | bs2000 \
+			| c[123]* | c30 | [cjt]90 | c4x \
+			| c8051 | clipper | craynv | csky | cydra \
+			| d10v | d30v | dlx | dsp16xx \
+			| e2k | elxsi | epiphany \
+			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+			| h8300 | h8500 \
+			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+			| hexagon \
+			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
+			| ip2k | iq2000 \
+			| k1om \
+			| le32 | le64 \
+			| lm32 \
+			| m32c | m32r | m32rle \
+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+			| m88110 | m88k | maxq | mb | mcore | mep | metag \
+			| microblaze | microblazeel \
+			| mips | mipsbe | mipseb | mipsel | mipsle \
+			| mips16 \
+			| mips64 | mips64eb | mips64el \
+			| mips64octeon | mips64octeonel \
+			| mips64orion | mips64orionel \
+			| mips64r5900 | mips64r5900el \
+			| mips64vr | mips64vrel \
+			| mips64vr4100 | mips64vr4100el \
+			| mips64vr4300 | mips64vr4300el \
+			| mips64vr5000 | mips64vr5000el \
+			| mips64vr5900 | mips64vr5900el \
+			| mipsisa32 | mipsisa32el \
+			| mipsisa32r2 | mipsisa32r2el \
+			| mipsisa32r6 | mipsisa32r6el \
+			| mipsisa64 | mipsisa64el \
+			| mipsisa64r2 | mipsisa64r2el \
+			| mipsisa64r6 | mipsisa64r6el \
+			| mipsisa64sb1 | mipsisa64sb1el \
+			| mipsisa64sr71k | mipsisa64sr71kel \
+			| mipsr5900 | mipsr5900el \
+			| mipstx39 | mipstx39el \
+			| mmix \
+			| mn10200 | mn10300 \
+			| moxie \
+			| mt \
+			| msp430 \
+			| nds32 | nds32le | nds32be \
+			| nfp \
+			| nios | nios2 | nios2eb | nios2el \
+			| none | np1 | ns16k | ns32k | nvptx \
+			| open8 \
+			| or1k* \
+			| or32 \
+			| orion \
+			| picochip \
+			| pdp10 | pdp11 | pj | pjl | pn | power \
+			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+			| pru \
+			| pyramid \
+			| riscv | riscv32 | riscv64 \
+			| rl78 | romp | rs6000 | rx \
+			| score \
+			| sh | shl \
+			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+			| sparclite \
+			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+			| spu \
+			| tahoe \
+			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+			| tron \
+			| ubicom32 \
+			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+			| vax \
+			| visium \
+			| w65 | wasm32 \
+			| we32k \
+			| x86 | x86_64 | xc16x | xgate | xps100 \
+			| xstormy16 | xtensa* \
+			| ymp \
+			| z8k | z80)
+				;;
+
+			*)
+				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+				exit 1
+				;;
+		esac
 		;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-	*-digital*)
-		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+case $vendor in
+	digital*)
+		vendor=dec
 		;;
-	*-commodore*)
-		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+	commodore*)
+		vendor=cbm
 		;;
 	*)
 		;;
@@ -1323,197 +1275,246 @@
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if [ x"$os" != x"" ]
+if [ x$os != x ]
 then
 case $os in
-	# First match some system type aliases
-	# that might get confused with valid system types.
-	# -solaris* is a basic system type, with this one exception.
-	-auroraux)
-		os=-auroraux
+	# First match some system type aliases that might get confused
+	# with valid system types.
+	# solaris* is a basic system type, with this one exception.
+	auroraux)
+		os=auroraux
 		;;
-	-solaris1 | -solaris1.*)
+	bluegene*)
+		os=cnk
+		;;
+	solaris1 | solaris1.*)
 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 		;;
-	-solaris)
-		os=-solaris2
+	solaris)
+		os=solaris2
 		;;
-	-svr4*)
-		os=-sysv4
+	unixware*)
+		os=sysv4.2uw
 		;;
-	-unixware*)
-		os=-sysv4.2uw
-		;;
-	-gnu/linux*)
+	gnu/linux*)
 		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
 		;;
-	# First accept the basic system types.
+	# es1800 is here to avoid being matched by es* (a different OS)
+	es1800*)
+		os=ose
+		;;
+	# Some version numbers need modification
+	chorusos*)
+		os=chorusos
+		;;
+	isc)
+		os=isc2.2
+		;;
+	sco6)
+		os=sco5v6
+		;;
+	sco5)
+		os=sco3.2v5
+		;;
+	sco4)
+		os=sco3.2v4
+		;;
+	sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		;;
+	sco3.2v[4-9]* | sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		;;
+	scout)
+		# Don't match below
+		;;
+	sco*)
+		os=sco3.2v2
+		;;
+	psos*)
+		os=psos
+		;;
+	# Now accept the basic system types.
 	# The portable systems comes first.
-	# Each alternative MUST END IN A *, to match a version number.
-	# -sysv* is not here because it comes later, after sysvr4.
-	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-	      | -sym* | -kopensolaris* | -plan9* \
-	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* \
-	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* \
-	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* \
-	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Each alternative MUST end in a * to match a version number.
+	# sysv* is not here because it comes later, after sysvr4.
+	gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
+	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+	     | sym* | kopensolaris* | plan9* \
+	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+	     | aos* | aros* | cloudabi* | sortix* \
+	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+	     | knetbsd* | mirbsd* | netbsd* \
+	     | bitrig* | openbsd* | solidbsd* | libertybsd* \
+	     | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
+	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+	     | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
+	     | chorusrdb* | cegcc* | glidix* \
+	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+	     | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
+	     | linux-newlib* | linux-musl* | linux-uclibc* \
+	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+	     | interix* | uwin* | mks* | rhapsody* | darwin* \
+	     | openstep* | oskit* | conix* | pw32* | nonstopux* \
+	     | storm-chaos* | tops10* | tenex* | tops20* | its* \
+	     | os2* | vos* | palmos* | uclinux* | nucleus* \
+	     | morphos* | superux* | rtmk* | windiss* \
+	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+	     | midnightbsd* | amdhsa* | unleashed* | emscripten*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
+	qnx*)
+		case $cpu in
+		    x86 | i*86)
 			;;
 		    *)
-			os=-nto$os
+			os=nto-$os
 			;;
 		esac
 		;;
-	-nto-qnx*)
+	hiux*)
+		os=hiuxwe2
 		;;
-	-nto*)
+	nto-qnx*)
+		;;
+	nto*)
 		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 		;;
-	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+	sim | xray | os68k* | v88r* \
+	    | windows* | osx | abug | netware* | os9* \
+	    | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
 		;;
-	-mac*)
-		os=`echo $os | sed -e 's|mac|macos|'`
+	linux-dietlibc)
+		os=linux-dietlibc
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
-		;;
-	-linux*)
+	linux*)
 		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 		;;
-	-sunos5*)
-		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+	lynx*178)
+		os=lynxos178
 		;;
-	-sunos6*)
-		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+	lynx*5)
+		os=lynxos5
 		;;
-	-opened*)
-		os=-openedition
+	lynx*)
+		os=lynxos
 		;;
-	-os400*)
-		os=-os400
+	mac*)
+		os=`echo "$os" | sed -e 's|mac|macos|'`
 		;;
-	-wince*)
-		os=-wince
+	opened*)
+		os=openedition
 		;;
-	-osfrose*)
-		os=-osfrose
+	os400*)
+		os=os400
 		;;
-	-osf*)
-		os=-osf
+	sunos5*)
+		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
 		;;
-	-utek*)
-		os=-bsd
+	sunos6*)
+		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+		;;
+	wince*)
+		os=wince
 		;;
-	-dynix*)
-		os=-bsd
+	utek*)
+		os=bsd
 		;;
-	-acis*)
-		os=-aos
+	dynix*)
+		os=bsd
 		;;
-	-atheos*)
-		os=-atheos
+	acis*)
+		os=aos
 		;;
-	-syllable*)
-		os=-syllable
+	atheos*)
+		os=atheos
+		;;
+	syllable*)
+		os=syllable
 		;;
-	-386bsd)
-		os=-bsd
+	386bsd)
+		os=bsd
 		;;
-	-ctix* | -uts*)
-		os=-sysv
+	ctix* | uts*)
+		os=sysv
 		;;
-	-nova*)
-		os=-rtmk-nova
+	nova*)
+		os=rtmk-nova
 		;;
-	-ns2 )
-		os=-nextstep2
+	ns2)
+		os=nextstep2
 		;;
-	-nsk*)
-		os=-nsk
+	nsk*)
+		os=nsk
 		;;
 	# Preserve the version number of sinix5.
-	-sinix5.*)
+	sinix5.*)
 		os=`echo $os | sed -e 's|sinix|sysv|'`
 		;;
-	-sinix*)
-		os=-sysv4
+	sinix*)
+		os=sysv4
 		;;
-	-tpf*)
-		os=-tpf
+	tpf*)
+		os=tpf
 		;;
-	-triton*)
-		os=-sysv3
+	triton*)
+		os=sysv3
 		;;
-	-oss*)
-		os=-sysv3
+	oss*)
+		os=sysv3
 		;;
-	-svr4)
-		os=-sysv4
+	svr4*)
+		os=sysv4
 		;;
-	-svr3)
-		os=-sysv3
+	svr3)
+		os=sysv3
 		;;
-	-sysvr4)
-		os=-sysv4
+	sysvr4)
+		os=sysv4
 		;;
-	# This must come after -sysvr4.
-	-sysv*)
+	# This must come after sysvr4.
+	sysv*)
+		;;
+	ose*)
+		os=ose
 		;;
-	-ose*)
-		os=-ose
-		;;
-	-es1800*)
-		os=-ose
+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+		os=mint
 		;;
-	-xenix)
-		os=-xenix
+	zvmoe)
+		os=zvmoe
 		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
+	dicos*)
+		os=dicos
 		;;
-	-aros*)
-		os=-aros
-		;;
-	-zvmoe)
-		os=-zvmoe
+	pikeos*)
+		# Until real need of OS specific support for
+		# particular features comes up, bare metal
+		# configurations are quite functional.
+		case $cpu in
+		    arm*)
+			os=eabi
+			;;
+		    *)
+			os=elf
+			;;
+		esac
 		;;
-	-dicos*)
-		os=-dicos
+	nacl*)
+		;;
+	ios)
 		;;
-	-nacl*)
+	none)
 		;;
-	-none)
+	*-eabi)
 		;;
 	*)
-		# Get rid of the `-' at the beginning of $os.
-		os=`echo $os | sed 's/[^-]*-//'`
-		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
 		exit 1
 		;;
 esac
@@ -1529,264 +1530,265 @@
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+case $cpu-$vendor in
 	score-*)
-		os=-elf
+		os=elf
 		;;
 	spu-*)
-		os=-elf
+		os=elf
 		;;
 	*-acorn)
-		os=-riscix1.2
+		os=riscix1.2
 		;;
 	arm*-rebel)
-		os=-linux
+		os=linux
 		;;
 	arm*-semi)
-		os=-aout
+		os=aout
 		;;
 	c4x-* | tic4x-*)
-		os=-coff
+		os=coff
 		;;
 	c8051-*)
-		os=-elf
+		os=elf
+		;;
+	clipper-intergraph)
+		os=clix
 		;;
 	hexagon-*)
-		os=-elf
+		os=elf
 		;;
 	tic54x-*)
-		os=-coff
+		os=coff
 		;;
 	tic55x-*)
-		os=-coff
+		os=coff
 		;;
 	tic6x-*)
-		os=-coff
+		os=coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
-		os=-tops20
+		os=tops20
 		;;
 	pdp11-*)
-		os=-none
+		os=none
 		;;
 	*-dec | vax-*)
-		os=-ultrix4.2
+		os=ultrix4.2
 		;;
 	m68*-apollo)
-		os=-domain
+		os=domain
 		;;
 	i386-sun)
-		os=-sunos4.0.2
+		os=sunos4.0.2
 		;;
 	m68000-sun)
-		os=-sunos3
+		os=sunos3
 		;;
 	m68*-cisco)
-		os=-aout
+		os=aout
 		;;
 	mep-*)
-		os=-elf
+		os=elf
 		;;
 	mips*-cisco)
-		os=-elf
+		os=elf
 		;;
 	mips*-*)
-		os=-elf
-		;;
-	or1k-*)
-		os=-elf
+		os=elf
 		;;
 	or32-*)
-		os=-coff
+		os=coff
 		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
-		os=-sysv3
+		os=sysv3
 		;;
 	sparc-* | *-sun)
-		os=-sunos4.1.1
+		os=sunos4.1.1
+		;;
+	pru-*)
+		os=elf
 		;;
 	*-be)
-		os=-beos
-		;;
-	*-haiku)
-		os=-haiku
+		os=beos
 		;;
 	*-ibm)
-		os=-aix
+		os=aix
 		;;
 	*-knuth)
-		os=-mmixware
+		os=mmixware
 		;;
 	*-wec)
-		os=-proelf
+		os=proelf
 		;;
 	*-winbond)
-		os=-proelf
+		os=proelf
 		;;
 	*-oki)
-		os=-proelf
+		os=proelf
 		;;
 	*-hp)
-		os=-hpux
+		os=hpux
 		;;
 	*-hitachi)
-		os=-hiux
+		os=hiux
 		;;
 	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-		os=-sysv
+		os=sysv
 		;;
 	*-cbm)
-		os=-amigaos
+		os=amigaos
 		;;
 	*-dg)
-		os=-dgux
+		os=dgux
 		;;
 	*-dolphin)
-		os=-sysv3
+		os=sysv3
 		;;
 	m68k-ccur)
-		os=-rtu
+		os=rtu
 		;;
 	m88k-omron*)
-		os=-luna
-		;;
-	*-next )
-		os=-nextstep
-		;;
-	*-sequent)
-		os=-ptx
-		;;
-	*-crds)
-		os=-unos
-		;;
-	*-ns)
-		os=-genix
-		;;
-	i370-*)
-		os=-mvs
+		os=luna
 		;;
 	*-next)
-		os=-nextstep3
+		os=nextstep
+		;;
+	*-sequent)
+		os=ptx
+		;;
+	*-crds)
+		os=unos
+		;;
+	*-ns)
+		os=genix
+		;;
+	i370-*)
+		os=mvs
 		;;
 	*-gould)
-		os=-sysv
+		os=sysv
 		;;
 	*-highlevel)
-		os=-bsd
+		os=bsd
 		;;
 	*-encore)
-		os=-bsd
+		os=bsd
 		;;
 	*-sgi)
-		os=-irix
+		os=irix
 		;;
 	*-siemens)
-		os=-sysv4
+		os=sysv4
 		;;
 	*-masscomp)
-		os=-rtu
+		os=rtu
 		;;
 	f30[01]-fujitsu | f700-fujitsu)
-		os=-uxpv
+		os=uxpv
 		;;
 	*-rom68k)
-		os=-coff
+		os=coff
 		;;
 	*-*bug)
-		os=-coff
+		os=coff
 		;;
 	*-apple)
-		os=-macos
+		os=macos
 		;;
 	*-atari*)
-		os=-mint
+		os=mint
+		;;
+	*-wrs)
+		os=vxworks
 		;;
 	*)
-		os=-none
+		os=none
 		;;
 esac
 fi
 
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-	*-unknown)
+case $vendor in
+	unknown)
 		case $os in
-			-riscix*)
+			riscix*)
 				vendor=acorn
 				;;
-			-sunos*)
+			sunos*)
 				vendor=sun
 				;;
-			-cnk*|-aix*)
+			cnk*|-aix*)
 				vendor=ibm
 				;;
-			-beos*)
+			beos*)
 				vendor=be
 				;;
-			-hpux*)
+			hpux*)
 				vendor=hp
 				;;
-			-mpeix*)
+			mpeix*)
 				vendor=hp
 				;;
-			-hiux*)
+			hiux*)
 				vendor=hitachi
 				;;
-			-unos*)
+			unos*)
 				vendor=crds
 				;;
-			-dgux*)
+			dgux*)
 				vendor=dg
 				;;
-			-luna*)
+			luna*)
 				vendor=omron
 				;;
-			-genix*)
+			genix*)
 				vendor=ns
 				;;
-			-mvs* | -opened*)
+			clix*)
+				vendor=intergraph
+				;;
+			mvs* | opened*)
 				vendor=ibm
 				;;
-			-os400*)
+			os400*)
 				vendor=ibm
 				;;
-			-ptx*)
+			ptx*)
 				vendor=sequent
 				;;
-			-tpf*)
+			tpf*)
 				vendor=ibm
 				;;
-			-vxsim* | -vxworks* | -windiss*)
+			vxsim* | vxworks* | windiss*)
 				vendor=wrs
 				;;
-			-aux*)
+			aux*)
 				vendor=apple
 				;;
-			-hms*)
+			hms*)
 				vendor=hitachi
 				;;
-			-mpw* | -macos*)
+			mpw* | macos*)
 				vendor=apple
 				;;
-			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+			*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
 				vendor=atari
 				;;
-			-vos*)
+			vos*)
 				vendor=stratus
 				;;
 		esac
-		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
 		;;
 esac
 
-echo $basic_machine$os
+echo "$cpu-$vendor-$os"
 exit
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
--- a/configure.ac	Thu Mar 21 23:28:59 2019 +0800
+++ b/configure.ac	Fri Jun 26 21:07:34 2020 +0800
@@ -323,17 +323,39 @@
 	]
 )
 
+AC_ARG_ENABLE(plugin,
+	[  --enable-plugin         Enable support for External Public Key Authentication plug-in],
+	[
+		AC_DEFINE(DROPBEAR_PLUGIN, 1, External Public Key Authentication)
+		AC_MSG_NOTICE(Enabling support for External Public Key Authentication)
+		DROPBEAR_PLUGIN=1
+	],
+	[
+		AC_DEFINE(DROPBEAR_PLUGIN, 0, External Public Key Authentication)
+		DROPBEAR_PLUGIN=0
+	]
+
+)
+AC_SUBST(DROPBEAR_PLUGIN)
+
 AC_ARG_ENABLE(fuzz,
 	[  --enable-fuzz           Build fuzzing. Not recommended for deployment.],
 	[
-		AC_DEFINE(DROPBEAR_FUZZ, 1, Fuzzing)
-		AC_MSG_NOTICE(Enabling fuzzing)
-		DROPBEAR_FUZZ=1
-		# libfuzzer needs linking with c++ libraries
-		AC_PROG_CXX
+		if test "x$enableval" = "xyes"; then
+            AC_DEFINE(DROPBEAR_FUZZ, 1, Fuzzing)
+            AC_MSG_NOTICE(Enabling fuzzing)
+            DROPBEAR_FUZZ=1
+            # libfuzzer needs linking with c++ libraries
+            AC_PROG_CXX
+        else
+            AC_DEFINE(DROPBEAR_FUZZ, 0, Fuzzing)
+            AC_MSG_NOTICE(Disabling fuzzing)
+            DROPBEAR_FUZZ=0
+        fi
 	],
 	[
 		AC_DEFINE(DROPBEAR_FUZZ, 0, Fuzzing)
+		AC_MSG_NOTICE(Disabling fuzzing)
 		DROPBEAR_FUZZ=0
 	]
 
@@ -348,7 +370,8 @@
 	crypt.h \
 	pty.h libutil.h libgen.h inttypes.h stropts.h utmp.h \
 	utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h \
-	pam/pam_appl.h netinet/in_systm.h sys/uio.h linux/pkt_sched.h])
+	pam/pam_appl.h netinet/in_systm.h sys/uio.h linux/pkt_sched.h \
+	sys/random.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -504,28 +527,29 @@
 AC_CHECK_HEADERS([mach/mach_time.h])
 AC_CHECK_FUNCS(mach_absolute_time)
 
-AC_CHECK_FUNCS(explicit_bzero memset_s)
+AC_CHECK_FUNCS(explicit_bzero memset_s getrandom)
 
 AC_ARG_ENABLE(bundled-libtom,
 [  --enable-bundled-libtom       Force using bundled libtomcrypt/libtommath even if a system version exists.
   --disable-bundled-libtom      Force using system libtomcrypt/libtommath, fail if it does not exist.
-                                Default is to use system if available, otherwise bundled.],
+                                Default is to use system if available, otherwise bundled.
+                                Dropbear requires system libtommath >= 1.2.0 and libtomcrypt >= 1.18.0],
 	[
 		if test "x$enableval" = "xyes"; then
 			BUNDLED_LIBTOM=1
 			AC_MSG_NOTICE(Forcing bundled libtom*)
 		else
 			BUNDLED_LIBTOM=0
-			AC_CHECK_LIB(tommath, mp_exptmod, LIBTOM_LIBS="-ltommath $LIBTOM_LIBS",
-				[AC_MSG_ERROR([Missing system libtommath and --disable-bundled-libtom was specified])] )
-			AC_CHECK_LIB(tomcrypt, register_cipher, LIBTOM_LIBS="-ltomcrypt $LIBTOM_LIBS",
-				[AC_MSG_ERROR([Missing system libtomcrypt and --disable-bundled-libtom was specified])] )
+			AC_CHECK_LIB(tommath, mp_to_ubin, LIBTOM_LIBS="-ltommath $LIBTOM_LIBS",
+				[AC_MSG_ERROR([Missing/old system libtommath and --disable-bundled-libtom was specified])] )
+			AC_CHECK_LIB(tomcrypt, poly1305_init, LIBTOM_LIBS="-ltomcrypt $LIBTOM_LIBS",
+				[AC_MSG_ERROR([Missing/old system libtomcrypt and --disable-bundled-libtom was specified])] )
 		fi
 	],
 	[
 		BUNDLED_LIBTOM=0
-		AC_CHECK_LIB(tommath, mp_exptmod, LIBTOM_LIBS="-ltommath $LIBTOM_LIBS", BUNDLED_LIBTOM=1)
-		AC_CHECK_LIB(tomcrypt, register_cipher, LIBTOM_LIBS="-ltomcrypt $LIBTOM_LIBS", BUNDLED_LIBTOM=1)
+		AC_CHECK_LIB(tommath, mp_to_ubin, LIBTOM_LIBS="-ltommath $LIBTOM_LIBS", BUNDLED_LIBTOM=1)
+		AC_CHECK_LIB(tomcrypt, poly1305_init, LIBTOM_LIBS="-ltomcrypt $LIBTOM_LIBS", BUNDLED_LIBTOM=1)
 	]
 )
 
@@ -858,4 +882,4 @@
 fi
 
 AC_MSG_NOTICE()
-AC_MSG_NOTICE([Now edit options.h to choose features.])
+AC_MSG_NOTICE([Now edit localoptions.h to choose features.])
--- a/curve25519-donna.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,860 +0,0 @@
-/* Copyright 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * curve25519-donna: Curve25519 elliptic curve, public key function
- *
- * http://code.google.com/p/curve25519-donna/
- *
- * Adam Langley <[email protected]>
- *
- * Derived from public domain C code by Daniel J. Bernstein <[email protected]>
- *
- * More information about curve25519 can be found here
- *   http://cr.yp.to/ecdh.html
- *
- * djb's sample implementation of curve25519 is written in a special assembly
- * language called qhasm and uses the floating point registers.
- *
- * This is, almost, a clean room reimplementation from the curve25519 paper. It
- * uses many of the tricks described therein. Only the crecip function is taken
- * from the sample implementation. */
-
-#include <string.h>
-#include <stdint.h>
-
-#ifdef _MSC_VER
-#define inline __inline
-#endif
-
-typedef uint8_t u8;
-typedef int32_t s32;
-typedef int64_t limb;
-
-/* Field element representation:
- *
- * Field elements are written as an array of signed, 64-bit limbs, least
- * significant first. The value of the field element is:
- *   x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
- *
- * i.e. the limbs are 26, 25, 26, 25, ... bits wide. */
-
-/* Sum two numbers: output += in */
-static void fsum(limb *output, const limb *in) {
-  unsigned i;
-  for (i = 0; i < 10; i += 2) {
-    output[0+i] = output[0+i] + in[0+i];
-    output[1+i] = output[1+i] + in[1+i];
-  }
-}
-
-/* Find the difference of two numbers: output = in - output
- * (note the order of the arguments!). */
-static void fdifference(limb *output, const limb *in) {
-  unsigned i;
-  for (i = 0; i < 10; ++i) {
-    output[i] = in[i] - output[i];
-  }
-}
-
-/* Multiply a number by a scalar: output = in * scalar */
-static void fscalar_product(limb *output, const limb *in, const limb scalar) {
-  unsigned i;
-  for (i = 0; i < 10; ++i) {
-    output[i] = in[i] * scalar;
-  }
-}
-
-/* Multiply two numbers: output = in2 * in
- *
- * output must be distinct to both inputs. The inputs are reduced coefficient
- * form, the output is not.
- *
- * output[x] <= 14 * the largest product of the input limbs. */
-static void fproduct(limb *output, const limb *in2, const limb *in) {
-  output[0] =       ((limb) ((s32) in2[0])) * ((s32) in[0]);
-  output[1] =       ((limb) ((s32) in2[0])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[0]);
-  output[2] =  2 *  ((limb) ((s32) in2[1])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[0]);
-  output[3] =       ((limb) ((s32) in2[1])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[0]);
-  output[4] =       ((limb) ((s32) in2[2])) * ((s32) in[2]) +
-               2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[0]);
-  output[5] =       ((limb) ((s32) in2[2])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[0]);
-  output[6] =  2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[0]);
-  output[7] =       ((limb) ((s32) in2[3])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[0]);
-  output[8] =       ((limb) ((s32) in2[4])) * ((s32) in[4]) +
-               2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[0]);
-  output[9] =       ((limb) ((s32) in2[4])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[0]);
-  output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[2]);
-  output[11] =      ((limb) ((s32) in2[5])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[2]);
-  output[12] =      ((limb) ((s32) in2[6])) * ((s32) in[6]) +
-               2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[3])) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[4]);
-  output[13] =      ((limb) ((s32) in2[6])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[4]);
-  output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[5])) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[6]);
-  output[15] =      ((limb) ((s32) in2[7])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[6]);
-  output[16] =      ((limb) ((s32) in2[8])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[7]));
-  output[17] =      ((limb) ((s32) in2[8])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[8]);
-  output[18] = 2 *  ((limb) ((s32) in2[9])) * ((s32) in[9]);
-}
-
-/* Reduce a long form to a short form by taking the input mod 2^255 - 19.
- *
- * On entry: |output[i]| < 14*2^54
- * On exit: |output[0..8]| < 280*2^54 */
-static void freduce_degree(limb *output) {
-  /* Each of these shifts and adds ends up multiplying the value by 19.
-   *
-   * For output[0..8], the absolute entry value is < 14*2^54 and we add, at
-   * most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */
-  output[8] += output[18] << 4;
-  output[8] += output[18] << 1;
-  output[8] += output[18];
-  output[7] += output[17] << 4;
-  output[7] += output[17] << 1;
-  output[7] += output[17];
-  output[6] += output[16] << 4;
-  output[6] += output[16] << 1;
-  output[6] += output[16];
-  output[5] += output[15] << 4;
-  output[5] += output[15] << 1;
-  output[5] += output[15];
-  output[4] += output[14] << 4;
-  output[4] += output[14] << 1;
-  output[4] += output[14];
-  output[3] += output[13] << 4;
-  output[3] += output[13] << 1;
-  output[3] += output[13];
-  output[2] += output[12] << 4;
-  output[2] += output[12] << 1;
-  output[2] += output[12];
-  output[1] += output[11] << 4;
-  output[1] += output[11] << 1;
-  output[1] += output[11];
-  output[0] += output[10] << 4;
-  output[0] += output[10] << 1;
-  output[0] += output[10];
-}
-
-#if (-1 & 3) != 3
-#error "This code only works on a two's complement system"
-#endif
-
-/* return v / 2^26, using only shifts and adds.
- *
- * On entry: v can take any value. */
-static inline limb
-div_by_2_26(const limb v)
-{
-  /* High word of v; no shift needed. */
-  const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
-  /* Set to all 1s if v was negative; else set to 0s. */
-  const int32_t sign = ((int32_t) highword) >> 31;
-  /* Set to 0x3ffffff if v was negative; else set to 0. */
-  const int32_t roundoff = ((uint32_t) sign) >> 6;
-  /* Should return v / (1<<26) */
-  return (v + roundoff) >> 26;
-}
-
-/* return v / (2^25), using only shifts and adds.
- *
- * On entry: v can take any value. */
-static inline limb
-div_by_2_25(const limb v)
-{
-  /* High word of v; no shift needed*/
-  const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
-  /* Set to all 1s if v was negative; else set to 0s. */
-  const int32_t sign = ((int32_t) highword) >> 31;
-  /* Set to 0x1ffffff if v was negative; else set to 0. */
-  const int32_t roundoff = ((uint32_t) sign) >> 7;
-  /* Should return v / (1<<25) */
-  return (v + roundoff) >> 25;
-}
-
-/* Reduce all coefficients of the short form input so that |x| < 2^26.
- *
- * On entry: |output[i]| < 280*2^54 */
-static void freduce_coefficients(limb *output) {
-  unsigned i;
-
-  output[10] = 0;
-
-  for (i = 0; i < 10; i += 2) {
-    limb over = div_by_2_26(output[i]);
-    /* The entry condition (that |output[i]| < 280*2^54) means that over is, at
-     * most, 280*2^28 in the first iteration of this loop. This is added to the
-     * next limb and we can approximate the resulting bound of that limb by
-     * 281*2^54. */
-    output[i] -= over << 26;
-    output[i+1] += over;
-
-    /* For the first iteration, |output[i+1]| < 281*2^54, thus |over| <
-     * 281*2^29. When this is added to the next limb, the resulting bound can
-     * be approximated as 281*2^54.
-     *
-     * For subsequent iterations of the loop, 281*2^54 remains a conservative
-     * bound and no overflow occurs. */
-    over = div_by_2_25(output[i+1]);
-    output[i+1] -= over << 25;
-    output[i+2] += over;
-  }
-  /* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */
-  output[0] += output[10] << 4;
-  output[0] += output[10] << 1;
-  output[0] += output[10];
-
-  output[10] = 0;
-
-  /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29
-   * So |over| will be no more than 2^16. */
-  {
-    limb over = div_by_2_26(output[0]);
-    output[0] -= over << 26;
-    output[1] += over;
-  }
-
-  /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The
-   * bound on |output[1]| is sufficient to meet our needs. */
-}
-
-/* A helpful wrapper around fproduct: output = in * in2.
- *
- * On entry: |in[i]| < 2^27 and |in2[i]| < 2^27.
- *
- * output must be distinct to both inputs. The output is reduced degree
- * (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */
-static void
-fmul(limb *output, const limb *in, const limb *in2) {
-  limb t[19];
-  fproduct(t, in, in2);
-  /* |t[i]| < 14*2^54 */
-  freduce_degree(t);
-  freduce_coefficients(t);
-  /* |t[i]| < 2^26 */
-  memcpy(output, t, sizeof(limb) * 10);
-}
-
-/* Square a number: output = in**2
- *
- * output must be distinct from the input. The inputs are reduced coefficient
- * form, the output is not.
- *
- * output[x] <= 14 * the largest product of the input limbs. */
-static void fsquare_inner(limb *output, const limb *in) {
-  output[0] =       ((limb) ((s32) in[0])) * ((s32) in[0]);
-  output[1] =  2 *  ((limb) ((s32) in[0])) * ((s32) in[1]);
-  output[2] =  2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[2]));
-  output[3] =  2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[3]));
-  output[4] =       ((limb) ((s32) in[2])) * ((s32) in[2]) +
-               4 *  ((limb) ((s32) in[1])) * ((s32) in[3]) +
-               2 *  ((limb) ((s32) in[0])) * ((s32) in[4]);
-  output[5] =  2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[4]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[5]));
-  output[6] =  2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[4]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[6]) +
-               2 *  ((limb) ((s32) in[1])) * ((s32) in[5]));
-  output[7] =  2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[5]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[7]));
-  output[8] =       ((limb) ((s32) in[4])) * ((s32) in[4]) +
-               2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[5])));
-  output[9] =  2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[9]));
-  output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
-                    ((limb) ((s32) in[4])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[9])));
-  output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[4])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[9]));
-  output[12] =      ((limb) ((s32) in[6])) * ((s32) in[6]) +
-               2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[9])));
-  output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[5])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[4])) * ((s32) in[9]));
-  output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[6])) * ((s32) in[8]) +
-               2 *  ((limb) ((s32) in[5])) * ((s32) in[9]));
-  output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[6])) * ((s32) in[9]));
-  output[16] =      ((limb) ((s32) in[8])) * ((s32) in[8]) +
-               4 *  ((limb) ((s32) in[7])) * ((s32) in[9]);
-  output[17] = 2 *  ((limb) ((s32) in[8])) * ((s32) in[9]);
-  output[18] = 2 *  ((limb) ((s32) in[9])) * ((s32) in[9]);
-}
-
-/* fsquare sets output = in^2.
- *
- * On entry: The |in| argument is in reduced coefficients form and |in[i]| <
- * 2^27.
- *
- * On exit: The |output| argument is in reduced coefficients form (indeed, one
- * need only provide storage for 10 limbs) and |out[i]| < 2^26. */
-static void
-fsquare(limb *output, const limb *in) {
-  limb t[19];
-  fsquare_inner(t, in);
-  /* |t[i]| < 14*2^54 because the largest product of two limbs will be <
-   * 2^(27+27) and fsquare_inner adds together, at most, 14 of those
-   * products. */
-  freduce_degree(t);
-  freduce_coefficients(t);
-  /* |t[i]| < 2^26 */
-  memcpy(output, t, sizeof(limb) * 10);
-}
-
-/* Take a little-endian, 32-byte number and expand it into polynomial form */
-static void
-fexpand(limb *output, const u8 *input) {
-#define F(n,start,shift,mask) \
-  output[n] = ((((limb) input[start + 0]) | \
-                ((limb) input[start + 1]) << 8 | \
-                ((limb) input[start + 2]) << 16 | \
-                ((limb) input[start + 3]) << 24) >> shift) & mask;
-  F(0, 0, 0, 0x3ffffff);
-  F(1, 3, 2, 0x1ffffff);
-  F(2, 6, 3, 0x3ffffff);
-  F(3, 9, 5, 0x1ffffff);
-  F(4, 12, 6, 0x3ffffff);
-  F(5, 16, 0, 0x1ffffff);
-  F(6, 19, 1, 0x3ffffff);
-  F(7, 22, 3, 0x1ffffff);
-  F(8, 25, 4, 0x3ffffff);
-  F(9, 28, 6, 0x1ffffff);
-#undef F
-}
-
-#if (-32 >> 1) != -16
-#error "This code only works when >> does sign-extension on negative numbers"
-#endif
-
-/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */
-static s32 s32_eq(s32 a, s32 b) {
-  a = ~(a ^ b);
-  a &= a << 16;
-  a &= a << 8;
-  a &= a << 4;
-  a &= a << 2;
-  a &= a << 1;
-  return a >> 31;
-}
-
-/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
- * both non-negative. */
-static s32 s32_gte(s32 a, s32 b) {
-  a -= b;
-  /* a >= 0 iff a >= b. */
-  return ~(a >> 31);
-}
-
-/* Take a fully reduced polynomial form number and contract it into a
- * little-endian, 32-byte array.
- *
- * On entry: |input_limbs[i]| < 2^26 */
-static void
-fcontract(u8 *output, limb *input_limbs) {
-  int i;
-  int j;
-  s32 input[10];
-  s32 mask;
-
-  /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
-  for (i = 0; i < 10; i++) {
-    input[i] = input_limbs[i];
-  }
-
-  for (j = 0; j < 2; ++j) {
-    for (i = 0; i < 9; ++i) {
-      if ((i & 1) == 1) {
-        /* This calculation is a time-invariant way to make input[i]
-         * non-negative by borrowing from the next-larger limb. */
-        const s32 mask = input[i] >> 31;
-        const s32 carry = -((input[i] & mask) >> 25);
-        input[i] = input[i] + (carry << 25);
-        input[i+1] = input[i+1] - carry;
-      } else {
-        const s32 mask = input[i] >> 31;
-        const s32 carry = -((input[i] & mask) >> 26);
-        input[i] = input[i] + (carry << 26);
-        input[i+1] = input[i+1] - carry;
-      }
-    }
-
-    /* There's no greater limb for input[9] to borrow from, but we can multiply
-     * by 19 and borrow from input[0], which is valid mod 2^255-19. */
-    {
-      const s32 mask = input[9] >> 31;
-      const s32 carry = -((input[9] & mask) >> 25);
-      input[9] = input[9] + (carry << 25);
-      input[0] = input[0] - (carry * 19);
-    }
-
-    /* After the first iteration, input[1..9] are non-negative and fit within
-     * 25 or 26 bits, depending on position. However, input[0] may be
-     * negative. */
-  }
-
-  /* The first borrow-propagation pass above ended with every limb
-     except (possibly) input[0] non-negative.
-
-     If input[0] was negative after the first pass, then it was because of a
-     carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
-     one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.
-
-     In the second pass, each limb is decreased by at most one. Thus the second
-     borrow-propagation pass could only have wrapped around to decrease
-     input[0] again if the first pass left input[0] negative *and* input[1]
-     through input[9] were all zero.  In that case, input[1] is now 2^25 - 1,
-     and this last borrow-propagation step will leave input[1] non-negative. */
-  {
-    const s32 mask = input[0] >> 31;
-    const s32 carry = -((input[0] & mask) >> 26);
-    input[0] = input[0] + (carry << 26);
-    input[1] = input[1] - carry;
-  }
-
-  /* All input[i] are now non-negative. However, there might be values between
-   * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
-  for (j = 0; j < 2; j++) {
-    for (i = 0; i < 9; i++) {
-      if ((i & 1) == 1) {
-        const s32 carry = input[i] >> 25;
-        input[i] &= 0x1ffffff;
-        input[i+1] += carry;
-      } else {
-        const s32 carry = input[i] >> 26;
-        input[i] &= 0x3ffffff;
-        input[i+1] += carry;
-      }
-    }
-
-    {
-      const s32 carry = input[9] >> 25;
-      input[9] &= 0x1ffffff;
-      input[0] += 19*carry;
-    }
-  }
-
-  /* If the first carry-chain pass, just above, ended up with a carry from
-   * input[9], and that caused input[0] to be out-of-bounds, then input[0] was
-   * < 2^26 + 2*19, because the carry was, at most, two.
-   *
-   * If the second pass carried from input[9] again then input[0] is < 2*19 and
-   * the input[9] -> input[0] carry didn't push input[0] out of bounds. */
-
-  /* It still remains the case that input might be between 2^255-19 and 2^255.
-   * In this case, input[1..9] must take their maximum value and input[0] must
-   * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
-  mask = s32_gte(input[0], 0x3ffffed);
-  for (i = 1; i < 10; i++) {
-    if ((i & 1) == 1) {
-      mask &= s32_eq(input[i], 0x1ffffff);
-    } else {
-      mask &= s32_eq(input[i], 0x3ffffff);
-    }
-  }
-
-  /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
-   * this conditionally subtracts 2^255-19. */
-  input[0] -= mask & 0x3ffffed;
-
-  for (i = 1; i < 10; i++) {
-    if ((i & 1) == 1) {
-      input[i] -= mask & 0x1ffffff;
-    } else {
-      input[i] -= mask & 0x3ffffff;
-    }
-  }
-
-  input[1] <<= 2;
-  input[2] <<= 3;
-  input[3] <<= 5;
-  input[4] <<= 6;
-  input[6] <<= 1;
-  input[7] <<= 3;
-  input[8] <<= 4;
-  input[9] <<= 6;
-#define F(i, s) \
-  output[s+0] |=  input[i] & 0xff; \
-  output[s+1]  = (input[i] >> 8) & 0xff; \
-  output[s+2]  = (input[i] >> 16) & 0xff; \
-  output[s+3]  = (input[i] >> 24) & 0xff;
-  output[0] = 0;
-  output[16] = 0;
-  F(0,0);
-  F(1,3);
-  F(2,6);
-  F(3,9);
-  F(4,12);
-  F(5,16);
-  F(6,19);
-  F(7,22);
-  F(8,25);
-  F(9,28);
-#undef F
-}
-
-/* Input: Q, Q', Q-Q'
- * Output: 2Q, Q+Q'
- *
- *   x2 z3: long form
- *   x3 z3: long form
- *   x z: short form, destroyed
- *   xprime zprime: short form, destroyed
- *   qmqp: short form, preserved
- *
- * On entry and exit, the absolute value of the limbs of all inputs and outputs
- * are < 2^26. */
-static void fmonty(limb *x2, limb *z2,  /* output 2Q */
-                   limb *x3, limb *z3,  /* output Q + Q' */
-                   limb *x, limb *z,    /* input Q */
-                   limb *xprime, limb *zprime,  /* input Q' */
-                   const limb *qmqp /* input Q - Q' */) {
-  limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
-        zzprime[19], zzzprime[19], xxxprime[19];
-
-  memcpy(origx, x, 10 * sizeof(limb));
-  fsum(x, z);
-  /* |x[i]| < 2^27 */
-  fdifference(z, origx);  /* does x - z */
-  /* |z[i]| < 2^27 */
-
-  memcpy(origxprime, xprime, sizeof(limb) * 10);
-  fsum(xprime, zprime);
-  /* |xprime[i]| < 2^27 */
-  fdifference(zprime, origxprime);
-  /* |zprime[i]| < 2^27 */
-  fproduct(xxprime, xprime, z);
-  /* |xxprime[i]| < 14*2^54: the largest product of two limbs will be <
-   * 2^(27+27) and fproduct adds together, at most, 14 of those products.
-   * (Approximating that to 2^58 doesn't work out.) */
-  fproduct(zzprime, x, zprime);
-  /* |zzprime[i]| < 14*2^54 */
-  freduce_degree(xxprime);
-  freduce_coefficients(xxprime);
-  /* |xxprime[i]| < 2^26 */
-  freduce_degree(zzprime);
-  freduce_coefficients(zzprime);
-  /* |zzprime[i]| < 2^26 */
-  memcpy(origxprime, xxprime, sizeof(limb) * 10);
-  fsum(xxprime, zzprime);
-  /* |xxprime[i]| < 2^27 */
-  fdifference(zzprime, origxprime);
-  /* |zzprime[i]| < 2^27 */
-  fsquare(xxxprime, xxprime);
-  /* |xxxprime[i]| < 2^26 */
-  fsquare(zzzprime, zzprime);
-  /* |zzzprime[i]| < 2^26 */
-  fproduct(zzprime, zzzprime, qmqp);
-  /* |zzprime[i]| < 14*2^52 */
-  freduce_degree(zzprime);
-  freduce_coefficients(zzprime);
-  /* |zzprime[i]| < 2^26 */
-  memcpy(x3, xxxprime, sizeof(limb) * 10);
-  memcpy(z3, zzprime, sizeof(limb) * 10);
-
-  fsquare(xx, x);
-  /* |xx[i]| < 2^26 */
-  fsquare(zz, z);
-  /* |zz[i]| < 2^26 */
-  fproduct(x2, xx, zz);
-  /* |x2[i]| < 14*2^52 */
-  freduce_degree(x2);
-  freduce_coefficients(x2);
-  /* |x2[i]| < 2^26 */
-  fdifference(zz, xx);  /* does zz = xx - zz */
-  /* |zz[i]| < 2^27 */
-  memset(zzz + 10, 0, sizeof(limb) * 9);
-  fscalar_product(zzz, zz, 121665);
-  /* |zzz[i]| < 2^(27+17) */
-  /* No need to call freduce_degree here:
-     fscalar_product doesn't increase the degree of its input. */
-  freduce_coefficients(zzz);
-  /* |zzz[i]| < 2^26 */
-  fsum(zzz, xx);
-  /* |zzz[i]| < 2^27 */
-  fproduct(z2, zz, zzz);
-  /* |z2[i]| < 14*2^(26+27) */
-  freduce_degree(z2);
-  freduce_coefficients(z2);
-  /* |z2|i| < 2^26 */
-}
-
-/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
- * them unchanged if 'iswap' is 0.  Runs in data-invariant time to avoid
- * side-channel attacks.
- *
- * NOTE that this function requires that 'iswap' be 1 or 0; other values give
- * wrong results.  Also, the two limb arrays must be in reduced-coefficient,
- * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
- * and all all values in a[0..9],b[0..9] must have magnitude less than
- * INT32_MAX. */
-static void
-swap_conditional(limb a[19], limb b[19], limb iswap) {
-  unsigned i;
-  const s32 swap = (s32) -iswap;
-
-  for (i = 0; i < 10; ++i) {
-    const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );
-    a[i] = ((s32)a[i]) ^ x;
-    b[i] = ((s32)b[i]) ^ x;
-  }
-}
-
-/* Calculates nQ where Q is the x-coordinate of a point on the curve
- *
- *   resultx/resultz: the x coordinate of the resulting curve point (short form)
- *   n: a little endian, 32-byte number
- *   q: a point of the curve (short form) */
-static void
-cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
-  limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
-  limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
-  limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
-  limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
-
-  unsigned i, j;
-
-  memcpy(nqpqx, q, sizeof(limb) * 10);
-
-  for (i = 0; i < 32; ++i) {
-    u8 byte = n[31 - i];
-    for (j = 0; j < 8; ++j) {
-      const limb bit = byte >> 7;
-
-      swap_conditional(nqx, nqpqx, bit);
-      swap_conditional(nqz, nqpqz, bit);
-      fmonty(nqx2, nqz2,
-             nqpqx2, nqpqz2,
-             nqx, nqz,
-             nqpqx, nqpqz,
-             q);
-      swap_conditional(nqx2, nqpqx2, bit);
-      swap_conditional(nqz2, nqpqz2, bit);
-
-      t = nqx;
-      nqx = nqx2;
-      nqx2 = t;
-      t = nqz;
-      nqz = nqz2;
-      nqz2 = t;
-      t = nqpqx;
-      nqpqx = nqpqx2;
-      nqpqx2 = t;
-      t = nqpqz;
-      nqpqz = nqpqz2;
-      nqpqz2 = t;
-
-      byte <<= 1;
-    }
-  }
-
-  memcpy(resultx, nqx, sizeof(limb) * 10);
-  memcpy(resultz, nqz, sizeof(limb) * 10);
-}
-
-/* -----------------------------------------------------------------------------
- * Shamelessly copied from djb's code
- * ----------------------------------------------------------------------------- */
-static void
-crecip(limb *out, const limb *z) {
-  limb z2[10];
-  limb z9[10];
-  limb z11[10];
-  limb z2_5_0[10];
-  limb z2_10_0[10];
-  limb z2_20_0[10];
-  limb z2_50_0[10];
-  limb z2_100_0[10];
-  limb t0[10];
-  limb t1[10];
-  int i;
-
-  /* 2 */ fsquare(z2,z);
-  /* 4 */ fsquare(t1,z2);
-  /* 8 */ fsquare(t0,t1);
-  /* 9 */ fmul(z9,t0,z);
-  /* 11 */ fmul(z11,z9,z2);
-  /* 22 */ fsquare(t0,z11);
-  /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
-
-  /* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
-  /* 2^7 - 2^2 */ fsquare(t1,t0);
-  /* 2^8 - 2^3 */ fsquare(t0,t1);
-  /* 2^9 - 2^4 */ fsquare(t1,t0);
-  /* 2^10 - 2^5 */ fsquare(t0,t1);
-  /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
-
-  /* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
-  /* 2^12 - 2^2 */ fsquare(t1,t0);
-  /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
-
-  /* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
-  /* 2^22 - 2^2 */ fsquare(t1,t0);
-  /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
-
-  /* 2^41 - 2^1 */ fsquare(t1,t0);
-  /* 2^42 - 2^2 */ fsquare(t0,t1);
-  /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
-  /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
-
-  /* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
-  /* 2^52 - 2^2 */ fsquare(t1,t0);
-  /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
-
-  /* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
-  /* 2^102 - 2^2 */ fsquare(t0,t1);
-  /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
-  /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
-
-  /* 2^201 - 2^1 */ fsquare(t0,t1);
-  /* 2^202 - 2^2 */ fsquare(t1,t0);
-  /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
-
-  /* 2^251 - 2^1 */ fsquare(t1,t0);
-  /* 2^252 - 2^2 */ fsquare(t0,t1);
-  /* 2^253 - 2^3 */ fsquare(t1,t0);
-  /* 2^254 - 2^4 */ fsquare(t0,t1);
-  /* 2^255 - 2^5 */ fsquare(t1,t0);
-  /* 2^255 - 21 */ fmul(out,t1,z11);
-}
-
-int
-curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
-  limb bp[10], x[10], z[11], zmone[10];
-  uint8_t e[32];
-  int i;
-
-  for (i = 0; i < 32; ++i) e[i] = secret[i];
-  e[0] &= 248;
-  e[31] &= 127;
-  e[31] |= 64;
-
-  fexpand(bp, basepoint);
-  cmult(x, z, e, bp);
-  crecip(zmone, z);
-  fmul(z, x, zmone);
-  fcontract(mypublic, z);
-  return 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/curve25519.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,497 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "dbrandom.h"
+#include "curve25519.h"
+
+#if DROPBEAR_CURVE25519 || DROPBEAR_ED25519
+
+/* Modified TweetNaCl version 20140427, a self-contained public-domain C library.
+ * https://tweetnacl.cr.yp.to/ */
+
+#define FOR(i,n) for (i = 0;i < n;++i)
+#define sv static void
+
+typedef unsigned char u8;
+typedef unsigned long u32;
+typedef unsigned long long u64;
+typedef long long i64;
+typedef i64 gf[16];
+
+#if DROPBEAR_CURVE25519
+static const gf
+  _121665 = {0xDB41,1};
+#endif /* DROPBEAR_CURVE25519 */
+#if DROPBEAR_ED25519
+static const gf
+  gf0,
+  gf1 = {1},
+  D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
+  X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
+  Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666};
+#if DROPBEAR_SIGNKEY_VERIFY
+static const gf
+  D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
+  I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
+#endif /* DROPBEAR_SIGNKEY_VERIFY */
+#endif /* DROPBEAR_ED25519 */
+
+#if DROPBEAR_ED25519
+#if DROPBEAR_SIGNKEY_VERIFY
+static int vn(const u8 *x,const u8 *y,u32 n)
+{
+  u32 i,d = 0;
+  FOR(i,n) d |= x[i]^y[i];
+  return (1 & ((d - 1) >> 8)) - 1;
+}
+
+static int crypto_verify_32(const u8 *x,const u8 *y)
+{
+  return vn(x,y,32);
+}
+#endif /* DROPBEAR_SIGNKEY_VERIFY */
+
+sv set25519(gf r, const gf a)
+{
+  int i;
+  FOR(i,16) r[i]=a[i];
+}
+#endif /* DROPBEAR_ED25519 */
+
+sv car25519(gf o)
+{
+  int i;
+  i64 c;
+  FOR(i,16) {
+    o[i]+=(1LL<<16);
+    c=o[i]>>16;
+    o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
+    o[i]-=c<<16;
+  }
+}
+
+sv sel25519(gf p,gf q,int b)
+{
+  i64 t,i,c=~(b-1);
+  FOR(i,16) {
+    t= c&(p[i]^q[i]);
+    p[i]^=t;
+    q[i]^=t;
+  }
+}
+
+sv pack25519(u8 *o,const gf n)
+{
+  int i,j,b;
+  gf m,t;
+  FOR(i,16) t[i]=n[i];
+  car25519(t);
+  car25519(t);
+  car25519(t);
+  FOR(j,2) {
+    m[0]=t[0]-0xffed;
+    for(i=1;i<15;i++) {
+      m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
+      m[i-1]&=0xffff;
+    }
+    m[15]=t[15]-0x7fff-((m[14]>>16)&1);
+    b=(m[15]>>16)&1;
+    m[14]&=0xffff;
+    sel25519(t,m,1-b);
+  }
+  FOR(i,16) {
+    o[2*i]=t[i]&0xff;
+    o[2*i+1]=t[i]>>8;
+  }
+}
+
+#if DROPBEAR_ED25519
+#if DROPBEAR_SIGNKEY_VERIFY
+static int neq25519(const gf a, const gf b)
+{
+  u8 c[32],d[32];
+  pack25519(c,a);
+  pack25519(d,b);
+  return crypto_verify_32(c,d);
+}
+#endif /* DROPBEAR_SIGNKEY_VERIFY */
+
+static u8 par25519(const gf a)
+{
+  u8 d[32];
+  pack25519(d,a);
+  return d[0]&1;
+}
+#endif /* DROPBEAR_ED25519 */
+
+sv unpack25519(gf o, const u8 *n)
+{
+  int i;
+  FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
+  o[15]&=0x7fff;
+}
+
+sv A(gf o,const gf a,const gf b)
+{
+  int i;
+  FOR(i,16) o[i]=a[i]+b[i];
+}
+
+sv Z(gf o,const gf a,const gf b)
+{
+  int i;
+  FOR(i,16) o[i]=a[i]-b[i];
+}
+
+sv M(gf o,const gf a,const gf b)
+{
+  i64 i,j,t[31];
+  FOR(i,31) t[i]=0;
+  FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
+  FOR(i,15) t[i]+=38*t[i+16];
+  FOR(i,16) o[i]=t[i];
+  car25519(o);
+  car25519(o);
+}
+
+sv S(gf o,const gf a)
+{
+  M(o,a,a);
+}
+
+sv inv25519(gf o,const gf i)
+{
+  gf c;
+  int a;
+  FOR(a,16) c[a]=i[a];
+  for(a=253;a>=0;a--) {
+    S(c,c);
+    if(a!=2&&a!=4) M(c,c,i);
+  }
+  FOR(a,16) o[a]=c[a];
+}
+
+#if DROPBEAR_ED25519 && DROPBEAR_SIGNKEY_VERIFY
+sv pow2523(gf o,const gf i)
+{
+  gf c;
+  int a;
+  FOR(a,16) c[a]=i[a];
+  for(a=250;a>=0;a--) {
+    S(c,c);
+    if(a!=1) M(c,c,i);
+  }
+  FOR(a,16) o[a]=c[a];
+}
+#endif /* DROPBEAR_ED25519 && DROPBEAR_SIGNKEY_VERIFY */
+
+#if DROPBEAR_CURVE25519
+void dropbear_curve25519_scalarmult(u8 *q,const u8 *n,const u8 *p)
+{
+  u8 z[32];
+  i64 x[80],r,i;
+  gf a,b,c,d,e,f;
+  FOR(i,31) z[i]=n[i];
+  z[31]=(n[31]&127)|64;
+  z[0]&=248;
+  unpack25519(x,p);
+  FOR(i,16) {
+    b[i]=x[i];
+    d[i]=a[i]=c[i]=0;
+  }
+  a[0]=d[0]=1;
+  for(i=254;i>=0;--i) {
+    r=(z[i>>3]>>(i&7))&1;
+    sel25519(a,b,r);
+    sel25519(c,d,r);
+    A(e,a,c);
+    Z(a,a,c);
+    A(c,b,d);
+    Z(b,b,d);
+    S(d,e);
+    S(f,a);
+    M(a,c,a);
+    M(c,b,e);
+    A(e,a,c);
+    Z(a,a,c);
+    S(b,a);
+    Z(c,d,f);
+    M(a,c,_121665);
+    A(a,a,d);
+    M(c,c,a);
+    M(a,d,f);
+    M(d,b,x);
+    S(b,e);
+    sel25519(a,b,r);
+    sel25519(c,d,r);
+  }
+  FOR(i,16) {
+    x[i+16]=a[i];
+    x[i+32]=c[i];
+    x[i+48]=b[i];
+    x[i+64]=d[i];
+  }
+  inv25519(x+32,x+32);
+  M(x+16,x+16,x+32);
+  pack25519(q,x+16);
+}
+#endif /* DROPBEAR_CURVE25519 */
+
+#if DROPBEAR_ED25519
+static int crypto_hash(u8 *out,const u8 *m,u64 n)
+{
+  hash_state hs;
+
+  sha512_init(&hs);
+  sha512_process(&hs, m, n);
+  return sha512_done(&hs, out);
+}
+
+sv add(gf p[4],gf q[4])
+{
+  gf a,b,c,d,t,e,f,g,h;
+  
+  Z(a, p[1], p[0]);
+  Z(t, q[1], q[0]);
+  M(a, a, t);
+  A(b, p[0], p[1]);
+  A(t, q[0], q[1]);
+  M(b, b, t);
+  M(c, p[3], q[3]);
+  M(c, c, D2);
+  M(d, p[2], q[2]);
+  A(d, d, d);
+  Z(e, b, a);
+  Z(f, d, c);
+  A(g, d, c);
+  A(h, b, a);
+
+  M(p[0], e, f);
+  M(p[1], h, g);
+  M(p[2], g, f);
+  M(p[3], e, h);
+}
+
+sv cswap(gf p[4],gf q[4],u8 b)
+{
+  int i;
+  FOR(i,4)
+    sel25519(p[i],q[i],b);
+}
+
+sv pack(u8 *r,gf p[4])
+{
+  gf tx, ty, zi;
+  inv25519(zi, p[2]); 
+  M(tx, p[0], zi);
+  M(ty, p[1], zi);
+  pack25519(r, ty);
+  r[31] ^= par25519(tx) << 7;
+}
+
+sv scalarmult(gf p[4],gf q[4],const u8 *s)
+{
+  int i;
+  set25519(p[0],gf0);
+  set25519(p[1],gf1);
+  set25519(p[2],gf1);
+  set25519(p[3],gf0);
+  for (i = 255;i >= 0;--i) {
+    u8 b = (s[i/8]>>(i&7))&1;
+    cswap(p,q,b);
+    add(q,p);
+    add(p,p);
+    cswap(p,q,b);
+  }
+}
+
+sv scalarbase(gf p[4],const u8 *s)
+{
+  gf q[4];
+  set25519(q[0],X);
+  set25519(q[1],Y);
+  set25519(q[2],gf1);
+  M(q[3],X,Y);
+  scalarmult(p,q,s);
+}
+
+void dropbear_ed25519_make_key(u8 *pk,u8 *sk)
+{
+  u8 d[64];
+  gf p[4];
+
+  genrandom(sk, 32);
+
+  crypto_hash(d, sk, 32);
+  d[0] &= 248;
+  d[31] &= 127;
+  d[31] |= 64;
+
+  scalarbase(p,d);
+  pack(pk,p);
+}
+
+static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
+
+sv modL(u8 *r,i64 x[64])
+{
+  i64 carry,i,j;
+  for (i = 63;i >= 32;--i) {
+    carry = 0;
+    for (j = i - 32;j < i - 12;++j) {
+      x[j] += carry - 16 * x[i] * L[j - (i - 32)];
+      carry = (x[j] + 128) >> 8;
+      x[j] -= carry << 8;
+    }
+    x[j] += carry;
+    x[i] = 0;
+  }
+  carry = 0;
+  FOR(j,32) {
+    x[j] += carry - (x[31] >> 4) * L[j];
+    carry = x[j] >> 8;
+    x[j] &= 255;
+  }
+  FOR(j,32) x[j] -= carry * L[j];
+  FOR(i,32) {
+    x[i+1] += x[i] >> 8;
+    r[i] = x[i] & 255;
+  }
+}
+
+sv reduce(u8 *r)
+{
+  i64 x[64],i;
+  FOR(i,64) x[i] = (u64) r[i];
+  FOR(i,64) r[i] = 0;
+  modL(r,x);
+}
+
+void dropbear_ed25519_sign(const u8 *m,u32 mlen,u8 *s,u32 *slen,const u8 *sk, const u8 *pk)
+{
+  hash_state hs;
+  u8 d[64],h[64],r[64];
+  i64 x[64];
+  gf p[4];
+  u32 i,j;
+
+  crypto_hash(d, sk, 32);
+  d[0] &= 248;
+  d[31] &= 127;
+  d[31] |= 64;
+
+  *slen = 64;
+
+  sha512_init(&hs);
+  sha512_process(&hs,d + 32,32);
+  sha512_process(&hs,m,mlen);
+  sha512_done(&hs,r);
+  reduce(r);
+  scalarbase(p,r);
+  pack(s,p);
+
+  sha512_init(&hs);
+  sha512_process(&hs,s,32);
+  sha512_process(&hs,pk,32);
+  sha512_process(&hs,m,mlen);
+  sha512_done(&hs,h);
+  reduce(h);
+
+  FOR(i,64) x[i] = 0;
+  FOR(i,32) x[i] = (u64) r[i];
+  FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
+  modL(s + 32,x);
+}
+
+#if DROPBEAR_SIGNKEY_VERIFY
+static int unpackneg(gf r[4],const u8 p[32])
+{
+  gf t, chk, num, den, den2, den4, den6;
+  set25519(r[2],gf1);
+  unpack25519(r[1],p);
+  S(num,r[1]);
+  M(den,num,D);
+  Z(num,num,r[2]);
+  A(den,r[2],den);
+
+  S(den2,den);
+  S(den4,den2);
+  M(den6,den4,den2);
+  M(t,den6,num);
+  M(t,t,den);
+
+  pow2523(t,t);
+  M(t,t,num);
+  M(t,t,den);
+  M(t,t,den);
+  M(r[0],t,den);
+
+  S(chk,r[0]);
+  M(chk,chk,den);
+  if (neq25519(chk, num)) M(r[0],r[0],I);
+
+  S(chk,r[0]);
+  M(chk,chk,den);
+  if (neq25519(chk, num)) return -1;
+
+  if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
+
+  M(r[3],r[0],r[1]);
+  return 0;
+}
+
+int dropbear_ed25519_verify(const u8 *m,u32 mlen,const u8 *s,u32 slen,const u8 *pk)
+{
+  hash_state hs;
+  u8 t[32],h[64];
+  gf p[4],q[4];
+
+  if (slen < 64) return -1;
+
+  if (unpackneg(q,pk)) return -1;
+
+  sha512_init(&hs);
+  sha512_process(&hs,s,32);
+  sha512_process(&hs,pk,32);
+  sha512_process(&hs,m,mlen);
+  sha512_done(&hs,h);
+
+  reduce(h);
+  scalarmult(p,q,h);
+
+  scalarbase(q,s + 32);
+  add(p,q);
+  pack(t,p);
+
+  if (crypto_verify_32(s, t))
+    return -1;
+
+  return 0;
+}
+#endif /* DROPBEAR_SIGNKEY_VERIFY */
+
+#endif /* DROPBEAR_ED25519 */
+
+#endif /* DROPBEAR_CURVE25519 || DROPBEAR_ED25519 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/curve25519.h	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,37 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef DROPBEAR_CURVE25519_H
+#define DROPBEAR_CURVE25519_H
+
+void dropbear_curve25519_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
+void dropbear_ed25519_make_key(unsigned char *pk, unsigned char  *sk);
+void dropbear_ed25519_sign(const unsigned char *m, unsigned long mlen,
+			  unsigned char *s, unsigned long *slen,
+			  const unsigned char *sk, const unsigned char *pk);
+int dropbear_ed25519_verify(const unsigned char *m, unsigned long mlen,
+			    const unsigned char *s, unsigned long slen,
+			    const unsigned char *pk);
+
+#endif /* DROPBEAR_CURVE25519_H */
--- a/dbmalloc.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/dbmalloc.c	Fri Jun 26 21:07:34 2020 +0800
@@ -180,3 +180,13 @@
 }
 
 #endif /* DROPBEAR_TRACKING_MALLOC */
+
+void * m_realloc_ltm(void* ptr, size_t oldsize, size_t newsize) {
+   (void)oldsize;
+   return m_realloc(ptr, newsize);
+}
+
+void m_free_ltm(void *mem, size_t size) {
+   (void)size;
+   m_free_direct(mem);
+}
--- a/dbrandom.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/dbrandom.c	Fri Jun 26 21:07:34 2020 +0800
@@ -49,24 +49,19 @@
  *
  */
 
-/* Pass len=0 to hash an entire file */
+/* Pass wantlen=0 to hash an entire file */
 static int
 process_file(hash_state *hs, const char *filename,
-		unsigned int len, int prngd)
-{
-	static int already_blocked = 0;
-	int readfd;
+		unsigned int wantlen, int prngd) {
+	int readfd = -1;
 	unsigned int readcount;
 	int ret = DROPBEAR_FAILURE;
 
+	if (prngd) {
 #if DROPBEAR_USE_PRNGD
-	if (prngd)
-	{
 		readfd = connect_unix(filename);
-	}
-	else
 #endif
-	{
+	} else {
 		readfd = open(filename, O_RDONLY);
 	}
 
@@ -75,58 +70,31 @@
 	}
 
 	readcount = 0;
-	while (len == 0 || readcount < len)
-	{
+	while (wantlen == 0 || readcount < wantlen) {
 		int readlen, wantread;
 		unsigned char readbuf[4096];
-		if (!already_blocked && !prngd)
-		{
-			int res;
-			struct timeval timeout;
-			fd_set read_fds;
-
- 			timeout.tv_sec  = 2;
- 			timeout.tv_usec = 0;
-
-			DROPBEAR_FD_ZERO(&read_fds);
-			FD_SET(readfd, &read_fds);
-			res = select(readfd + 1, &read_fds, NULL, NULL, &timeout);
-			if (res == 0)
-			{
-				dropbear_log(LOG_WARNING, "Warning: Reading the randomness source '%s' seems to have blocked.\nYou may need to find a better entropy source.", filename);
-				already_blocked = 1;
-			}
-		}
-
-		if (len == 0)
-		{
+		if (wantlen == 0) {
 			wantread = sizeof(readbuf);
-		} 
-		else
-		{
-			wantread = MIN(sizeof(readbuf), len-readcount);
+		} else {
+			wantread = MIN(sizeof(readbuf), wantlen-readcount);
 		}
 
 #if DROPBEAR_USE_PRNGD
-		if (prngd)
-		{
+		if (prngd) {
 			char egdcmd[2];
 			egdcmd[0] = 0x02;	/* blocking read */
 			egdcmd[1] = (unsigned char)wantread;
-			if (write(readfd, egdcmd, 2) < 0)
-			{
+			if (write(readfd, egdcmd, 2) < 0) {
 				dropbear_exit("Can't send command to egd");
 			}
 		}
 #endif
-
 		readlen = read(readfd, readbuf, wantread);
 		if (readlen <= 0) {
 			if (readlen < 0 && errno == EINTR) {
 				continue;
 			}
-			if (readlen == 0 && len == 0)
-			{
+			if (readlen == 0 && wantlen == 0) {
 				/* whole file was read as requested */
 				break;
 			}
@@ -193,6 +161,63 @@
 }
 #endif
 
+
+#ifdef HAVE_GETRANDOM
+/* Reads entropy seed with getrandom(). 
+ * May block if the kernel isn't ready.
+ * Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
+static int process_getrandom(hash_state *hs) {
+	char buf[INIT_SEED_SIZE];
+	ssize_t ret;
+
+	/* First try non-blocking so that we can warn about waiting */
+	ret = getrandom(buf, sizeof(buf), GRND_NONBLOCK);
+	if (ret == -1) {
+		if (errno == ENOSYS) {
+			/* Old kernel */
+			return DROPBEAR_FAILURE;
+		}
+		/* Other errors fall through to blocking getrandom() */
+		TRACE(("first getrandom() failed: %d %s", errno, strerror(errno)))
+		if (errno == EAGAIN) {
+			dropbear_log(LOG_WARNING, "Waiting for kernel randomness to be initialised...");
+		}
+	}
+
+	/* Wait blocking if needed. Loop in case we get EINTR */
+	while (ret != sizeof(buf)) {
+		ret = getrandom(buf, sizeof(buf), 0);
+
+		if (ret == sizeof(buf)) {
+			/* Success */
+			break;
+		}
+		if (ret == -1 && errno == EINTR) {
+			/* Try again. */
+			continue;
+		}
+		if (ret >= 0) {
+			TRACE(("Short read %zd from getrandom() shouldn't happen", ret))
+			/* Try again? */
+			continue;
+		}
+
+		/* Unexpected problem, fall back to /dev/urandom */
+		TRACE(("2nd getrandom() failed: %d %s", errno, strerror(errno)))
+		break;
+	}
+
+	if (ret == sizeof(buf)) {
+		/* Success, stir in the entropy */
+		sha1_process(hs, (void*)buf, sizeof(buf));
+		return DROPBEAR_SUCCESS;
+	}
+
+	return DROPBEAR_FAILURE;
+
+}
+#endif /* HAVE_GETRANDOM */
+
 /* Initialise the prng from /dev/urandom or prngd. This function can
  * be called multiple times */
 void seedrandom() {
@@ -202,6 +227,7 @@
 	pid_t pid;
 	struct timeval tv;
 	clock_t clockval;
+	int urandom_seeded = 0;
 
 #if DROPBEAR_FUZZ
 	if (fuzz.fuzzing) {
@@ -215,21 +241,31 @@
 	/* existing state */
 	sha1_process(&hs, (void*)hashpool, sizeof(hashpool));
 
-#if DROPBEAR_USE_PRNGD
-	if (process_file(&hs, DROPBEAR_PRNGD_SOCKET, INIT_SEED_SIZE, 1) 
-			!= DROPBEAR_SUCCESS) {
-		dropbear_exit("Failure reading random device %s", 
-				DROPBEAR_PRNGD_SOCKET);
-	}
-#else
-	/* non-blocking random source (probably /dev/urandom) */
-	if (process_file(&hs, DROPBEAR_URANDOM_DEV, INIT_SEED_SIZE, 0) 
-			!= DROPBEAR_SUCCESS) {
-		dropbear_exit("Failure reading random device %s", 
-				DROPBEAR_URANDOM_DEV);
+#ifdef HAVE_GETRANDOM
+	if (process_getrandom(&hs) == DROPBEAR_SUCCESS) {
+		urandom_seeded = 1;
 	}
 #endif
 
+	if (!urandom_seeded) {
+#if DROPBEAR_USE_PRNGD
+		if (process_file(&hs, DROPBEAR_PRNGD_SOCKET, INIT_SEED_SIZE, 1) 
+				!= DROPBEAR_SUCCESS) {
+			dropbear_exit("Failure reading random device %s", 
+					DROPBEAR_PRNGD_SOCKET);
+			urandom_seeded = 1;
+		}
+#else
+		/* non-blocking random source (probably /dev/urandom) */
+		if (process_file(&hs, DROPBEAR_URANDOM_DEV, INIT_SEED_SIZE, 0) 
+				!= DROPBEAR_SUCCESS) {
+			dropbear_exit("Failure reading random device %s", 
+					DROPBEAR_URANDOM_DEV);
+			urandom_seeded = 1;
+		}
+#endif
+	} /* urandom_seeded */
+
 	/* A few other sources to fall back on. 
 	 * Add more here for other platforms */
 #ifdef __linux__
--- a/debian/changelog	Thu Mar 21 23:28:59 2019 +0800
+++ b/debian/changelog	Fri Jun 26 21:07:34 2020 +0800
@@ -1,3 +1,21 @@
+dropbear (2020.79-0.1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matt Johnston <[email protected]>  Mon, 15 Jun 2020 22:51:57 +0800
+
+dropbear (2019.78-0.1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matt Johnston <[email protected]>  Wed, 27 Mar 2019 22:51:57 +0800
+
+dropbear (2019.77-0.1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matt Johnston <[email protected]>  Sat, 23 Mar 2019 22:51:57 +0800
+
 dropbear (2018.76-0.1) unstable; urgency=low
 
   * New upstream release.
--- a/debug.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/debug.h	Fri Jun 26 21:07:34 2020 +0800
@@ -43,12 +43,6 @@
 #define CHECKCLEARTOWRITE()
 #endif
 
-/* Define this, compile with -pg and set GMON_OUT_PREFIX=gmon to get gmon
- * output when Dropbear forks. This will allow it gprof to be used.
- * It's useful to run dropbear -F, so you don't fork as much */
-/* (This is Linux specific) */
-/*#define DEBUG_FORKGPROF*/
-
 /* A couple of flags, not usually useful, and mightn't do anything */
 
 /*#define DEBUG_KEXHASH*/
@@ -66,7 +60,9 @@
 
 /* To debug with GDB it is easier to run with no forking of child processes.
    You will need to pass "-F" as well. */
-/* #define DEBUG_NOFORK */
+#ifndef DEBUG_NOFORK
+#define DEBUG_NOFORK 0
+#endif
 
 
 /* For testing as non-root on shadowed systems, include the crypt of a password
--- a/default_options.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/default_options.h	Fri Jun 26 21:07:34 2020 +0800
@@ -22,6 +22,7 @@
 #define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key"
 #define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key"
 #define ECDSA_PRIV_FILENAME "/etc/dropbear/dropbear_ecdsa_host_key"
+#define ED25519_PRIV_FILENAME "/etc/dropbear/dropbear_ed25519_host_key"
 
 /* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens
  * on chosen ports and keeps accepting connections. This is the default.
@@ -47,7 +48,7 @@
 #define DROPBEAR_SMALL_CODE 1
 
 /* Enable X11 Forwarding - server only */
-#define DROPBEAR_X11FWD 1
+#define DROPBEAR_X11FWD 0
 
 /* Enable TCP Fowarding */
 /* 'Local' is "-L" style (client listening port forwarded via server)
@@ -82,27 +83,36 @@
  * Including both AES keysize variants (128 and 256) will result in 
  * a minimal size increase */
 #define DROPBEAR_AES128 1
-#define DROPBEAR_3DES 1
 #define DROPBEAR_AES256 1
+#define DROPBEAR_3DES 0
 #define DROPBEAR_TWOFISH256 0
 #define DROPBEAR_TWOFISH128 0
-/* Compiling in Blowfish will add ~6kB to runtime heap memory usage */
-#define DROPBEAR_BLOWFISH 0
+
+/* Enable Chacha20-Poly1305 authenticated encryption mode. This is
+ * generally faster than AES256 on CPU w/o dedicated AES instructions,
+ * having the same key size. Recommended.
+ * Compiling in will add ~5,5kB to binary size on x86-64 */
+#define DROPBEAR_CHACHA20POLY1305 1
+
+/* Enable "Counter Mode" for ciphers. Recommended. */
+#define DROPBEAR_ENABLE_CTR_MODE 1
 
 /* Enable CBC mode for ciphers. This has security issues though
- * is the most compatible with older SSH implementations */
-#define DROPBEAR_ENABLE_CBC_MODE 1
+   may be required for compatibility with old implementations */
+#define DROPBEAR_ENABLE_CBC_MODE 0
 
-/* Enable "Counter Mode" for ciphers. This is more secure than
- * CBC mode against certain attacks. It is recommended for security
- * and forwards compatibility */
-#define DROPBEAR_ENABLE_CTR_MODE 1
+/* Enable "Galois/Counter Mode" for ciphers. This authenticated
+ * encryption mode is combination of CTR mode and GHASH. Recommended
+ * for security and forwards compatibility, but slower than CTR on
+ * CPU w/o dedicated AES/GHASH instructions.
+ * Compiling in will add ~6kB to binary size on x86-64 */
+#define DROPBEAR_ENABLE_GCM_MODE 0
 
 /* Message integrity. sha2-256 is recommended as a default, 
    sha1 for compatibility */
 #define DROPBEAR_SHA1_HMAC 1
-#define DROPBEAR_SHA1_96_HMAC 1
 #define DROPBEAR_SHA2_256_HMAC 1
+#define DROPBEAR_SHA1_96_HMAC 0
 
 /* Hostkey/public key algorithms - at least one required, these are used
  * for hostkey as well as for verifying signatures with pubkey auth.
@@ -116,11 +126,15 @@
  * code (either ECDSA or ECDH) increases binary size - around 30kB
  * on x86-64 */
 #define DROPBEAR_ECDSA 1
+/* Ed25519 is faster than ECDSA. Compiling in Ed25519 code increases
+   binary size - around 7,5kB on x86-64 */
+#define DROPBEAR_ED25519 1
 
 /* RSA must be >=1024 */
 #define DROPBEAR_DEFAULT_RSA_SIZE 2048
 /* DSS is always 1024 */
 /* ECDSA defaults to largest size configured, usually 521 */
+/* Ed25519 is always 256 */
 
 /* Add runtime flag "-R" to generate hostkeys as-needed when the first 
    connection using that key type occurs.
@@ -143,7 +157,7 @@
  * group14 is supported by most implementations.
  * group16 provides a greater strength level but is slower and increases binary size
  * curve25519 and ecdh algorithms are faster than non-elliptic curve methods
- * curve25519 increases binary size by ~8kB on x86-64
+ * curve25519 increases binary size by ~2,5kB on x86-64
  * including either ECDH or ECDSA increases binary size by ~30kB on x86-64
 
  * Small systems should generally include either curve25519 or ecdh for performance.
@@ -174,7 +188,7 @@
 #define DO_HOST_LOOKUP 0
 
 /* Whether to print the message of the day (MOTD). */
-#define DO_MOTD 0
+#define DO_MOTD 1
 #define MOTD_FILENAME "/etc/motd"
 
 /* Authentication Types - at least one required.
--- a/dh_groups.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/dh_groups.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,6 +1,8 @@
 #include "options.h"
 #include "dh_groups.h"
 
+#if DROPBEAR_NORMAL_DH
+
 #if DROPBEAR_DH_GROUP1
 /* diffie-hellman-group1-sha1 value for p */
 const unsigned char dh_p_1[DH_P_1_LEN] = {
@@ -92,3 +94,4 @@
 /* Same for all groups */
 const int DH_G_VAL = 2;
 
+#endif /* DROPBEAR_NORMAL_DH */
--- a/dh_groups.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/dh_groups.h	Fri Jun 26 21:07:34 2020 +0800
@@ -2,6 +2,8 @@
 #define DROPBEAR_DH_GROUPS_H
 #include "options.h"
 
+#if DROPBEAR_NORMAL_DH
+
 #if DROPBEAR_DH_GROUP1
 #define DH_P_1_LEN 128
 extern const unsigned char dh_p_1[DH_P_1_LEN];
@@ -17,8 +19,8 @@
 extern const unsigned char dh_p_16[DH_P_16_LEN];
 #endif
 
-
 extern const int DH_G_VAL;
 
+#endif /* DROPBEAR_NORMAL_DH */
 
 #endif
--- a/dropbear.8	Thu Mar 21 23:28:59 2019 +0800
+++ b/dropbear.8	Fri Jun 26 21:07:34 2020 +0800
@@ -107,7 +107,7 @@
 Authorized Keys
 
 ~/.ssh/authorized_keys can be set up to allow remote login with a RSA,
-ECDSA, or DSS
+ECDSA, Ed25519 or DSS
 key. Each line is of the form
 .TP
 [restrictions] ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIgAsp... [comment]
@@ -146,8 +146,8 @@
 Host Key Files
 
 Host key files are read at startup from a standard location, by default
-/etc/dropbear/dropbear_dss_host_key, /etc/dropbear/dropbear_rsa_host_key, and 
-/etc/dropbear/dropbear_ecdsa_host_key
+/etc/dropbear/dropbear_dss_host_key, /etc/dropbear/dropbear_rsa_host_key,
+/etc/dropbear/dropbear_ecdsa_host_key and /etc/dropbear/dropbear_ed25519_host_key
 
 If the -r command line option is specified the default files are not loaded.
 Host key files are of the form generated by dropbearkey. 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dropbear_lint.sh	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+EXITCODE=0
+
+# #ifdef instead of #if
+grep '#ifdef DROPBEAR' -I *.c *.h && EXITCODE=1
+
+exit $EXITCODE
--- a/dropbearkey.1	Thu Mar 21 23:28:59 2019 +0800
+++ b/dropbearkey.1	Fri Jun 26 21:07:34 2020 +0800
@@ -13,7 +13,7 @@
 .SH DESCRIPTION
 .B dropbearkey
 generates a
-\fIRSA\fR, \fIDSS\fR, or \fIECDSA\fR
+\fIRSA\fR, \fIDSS\fR, \fIECDSA\fR, or \fIEd25519\fR
 format SSH private key, and saves it to a file for the use with the
 Dropbear client or server.
 Note that 
@@ -26,6 +26,7 @@
 Must be one of
 .I rsa
 .I ecdsa
+.I ed25519
 or
 .IR dss .
 .TP
--- a/dropbearkey.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/dropbearkey.c	Fri Jun 26 21:07:34 2020 +0800
@@ -43,6 +43,10 @@
  * mp_int	y
  * mp_int	x
  *
+ * Ed25519:
+ * string	"ssh-ed25519"
+ * string	k (32 bytes) + A (32 bytes)
+ *
  */
 #include "includes.h"
 #include "signkey.h"
@@ -51,6 +55,7 @@
 
 #include "genrsa.h"
 #include "gendss.h"
+#include "gened25519.h"
 #include "ecdsa.h"
 #include "crypto_desc.h"
 #include "dbrandom.h"
@@ -76,6 +81,9 @@
 #if DROPBEAR_ECDSA
 					"		ecdsa\n"
 #endif
+#if DROPBEAR_ED25519
+					"		ed25519\n"
+#endif
 					"-f filename    Use filename for the secret key.\n"
 					"               ~/.ssh/id_dropbear is recommended for client keys.\n"
 					"-s bits	Key size in bits, should be a multiple of 8 (optional)\n"
@@ -95,6 +103,9 @@
 #endif
 					"\n"
 #endif
+#if DROPBEAR_ED25519
+					"           Ed25519 has a fixed size of 256 bits\n"
+#endif
 					"-y		Just print the publickey and fingerprint for the\n		private key in <filename>.\n"
 #if DEBUG_TRACE
 					"-v		verbose\n"
@@ -106,6 +117,14 @@
 static void check_signkey_bits(enum signkey_type type, int bits)
 {
 	switch (type) {
+#if DROPBEAR_ED25519
+		case DROPBEAR_SIGNKEY_ED25519:
+			if (bits != 256) {
+				dropbear_exit("Ed25519 keys have a fixed size of 256 bits\n");
+				exit(EXIT_FAILURE);
+			}
+			break;
+#endif
 #if DROPBEAR_RSA
 		case DROPBEAR_SIGNKEY_RSA:
 			if (bits < 512 || bits > 4096 || (bits % 8 != 0)) {
@@ -114,7 +133,7 @@
 			}
 			break;
 #endif
-#ifdef DROPEAR_DSS
+#if DROPEAR_DSS
 		case DROPBEAR_SIGNKEY_DSS:
 			if (bits != 1024) {
 				dropbear_exit("DSS keys have a fixed size of 1024 bits\n");
@@ -224,6 +243,12 @@
 		keytype = DROPBEAR_SIGNKEY_ECDSA_KEYGEN;
 	}
 #endif
+#if DROPBEAR_ED25519
+	if (strcmp(typetext, "ed25519") == 0)
+	{
+		keytype = DROPBEAR_SIGNKEY_ED25519;
+	}
+#endif
 
 	if (keytype == DROPBEAR_SIGNKEY_NONE) {
 		fprintf(stderr, "Unknown key type '%s'\n", typetext);
--- a/dss.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/dss.c	Fri Jun 26 21:07:34 2020 +0800
@@ -284,6 +284,7 @@
 	unsigned char msghash[SHA1_HASH_SIZE];
 	unsigned int writelen;
 	unsigned int i;
+	size_t written;
 	DEF_MP_INT(dss_k);
 	DEF_MP_INT(dss_m);
 	DEF_MP_INT(dss_temp1);
@@ -340,31 +341,31 @@
 	buf_putstring(buf, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN);
 	buf_putint(buf, 2*SHA1_HASH_SIZE);
 
-	writelen = mp_unsigned_bin_size(&dss_r);
+	writelen = mp_ubin_size(&dss_r);
 	dropbear_assert(writelen <= SHA1_HASH_SIZE);
 	/* need to pad to 160 bits with leading zeros */
 	for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) {
 		buf_putbyte(buf, 0);
 	}
-	if (mp_to_unsigned_bin(&dss_r, buf_getwriteptr(buf, writelen)) 
+	if (mp_to_ubin(&dss_r, buf_getwriteptr(buf, writelen), writelen, &written)
 			!= MP_OKAY) {
 		dropbear_exit("DSS error");
 	}
 	mp_clear(&dss_r);
-	buf_incrwritepos(buf, writelen);
+	buf_incrwritepos(buf, written);
 
-	writelen = mp_unsigned_bin_size(&dss_s);
+	writelen = mp_ubin_size(&dss_s);
 	dropbear_assert(writelen <= SHA1_HASH_SIZE);
 	/* need to pad to 160 bits with leading zeros */
 	for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) {
 		buf_putbyte(buf, 0);
 	}
-	if (mp_to_unsigned_bin(&dss_s, buf_getwriteptr(buf, writelen)) 
+	if (mp_to_ubin(&dss_s, buf_getwriteptr(buf, writelen), writelen, &written)
 			!= MP_OKAY) {
 		dropbear_exit("DSS error");
 	}
 	mp_clear(&dss_s);
-	buf_incrwritepos(buf, writelen);
+	buf_incrwritepos(buf, written);
 
 	mp_clear_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s,
 			&dss_m, NULL);
--- a/dss.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/dss.h	Fri Jun 26 21:07:34 2020 +0800
@@ -30,7 +30,7 @@
 
 #if DROPBEAR_DSS 
 
-typedef struct {
+typedef struct dropbear_DSS_Key {
 
 	mp_int* p;
 	mp_int* q;
--- a/ecc.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/ecc.c	Fri Jun 26 21:07:34 2020 +0800
@@ -166,13 +166,13 @@
 	key = new_ecc_key();
 	key->dp = curve->dp;
 
-	if (mp_read_unsigned_bin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
+	if (mp_from_ubin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
 		TRACE(("failed to read x"))
 		goto out;
 	}
 	buf_incrpos(buf, size);
 
-	if (mp_read_unsigned_bin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
+	if (mp_from_ubin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
 		TRACE(("failed to read y"))
 		goto out;
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ed25519.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,182 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+/* Perform Ed25519 operations on data, including reading keys, signing and
+ * verification. */
+
+#include "includes.h"
+#include "dbutil.h"
+#include "buffer.h"
+#include "ssh.h"
+#include "curve25519.h"
+#include "ed25519.h"
+
+#if DROPBEAR_ED25519
+
+/* Load a public ed25519 key from a buffer, initialising the values.
+ * The key will have the same format as buf_put_ed25519_key.
+ * These should be freed with ed25519_key_free.
+ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
+int buf_get_ed25519_pub_key(buffer *buf, dropbear_ed25519_key *key) {
+
+	unsigned int len;
+
+	TRACE(("enter buf_get_ed25519_pub_key"))
+	dropbear_assert(key != NULL);
+
+	buf_incrpos(buf, 4+SSH_SIGNKEY_ED25519_LEN); /* int + "ssh-ed25519" */
+
+	len = buf_getint(buf);
+	if (len != CURVE25519_LEN || buf->len - buf->pos < len) {
+		TRACE(("leave buf_get_ed25519_pub_key: failure"))
+		return DROPBEAR_FAILURE;
+	}
+
+	m_burn(key->priv, CURVE25519_LEN);
+	memcpy(key->pub, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
+	buf_incrpos(buf, CURVE25519_LEN);
+
+	TRACE(("leave buf_get_ed25519_pub_key: success"))
+	return DROPBEAR_SUCCESS;
+}
+
+/* Same as buf_get_ed25519_pub_key, but reads private key at the end.
+ * Loads a public and private ed25519 key from a buffer
+ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
+int buf_get_ed25519_priv_key(buffer *buf, dropbear_ed25519_key *key) {
+
+	unsigned int len;
+
+	TRACE(("enter buf_get_ed25519_priv_key"))
+	dropbear_assert(key != NULL);
+
+	buf_incrpos(buf, 4+SSH_SIGNKEY_ED25519_LEN); /* int + "ssh-ed25519" */
+
+	len = buf_getint(buf);
+	if (len != CURVE25519_LEN*2 || buf->len - buf->pos < len) {
+		TRACE(("leave buf_get_ed25519_priv_key: failure"))
+		return DROPBEAR_FAILURE;
+	}
+
+	memcpy(key->priv, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
+	buf_incrpos(buf, CURVE25519_LEN);
+	memcpy(key->pub, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
+	buf_incrpos(buf, CURVE25519_LEN);
+
+	TRACE(("leave buf_get_ed25519_priv_key: success"))
+	return DROPBEAR_SUCCESS;
+}
+
+/* Clear and free the memory used by a public or private key */
+void ed25519_key_free(dropbear_ed25519_key *key) {
+
+	TRACE2(("enter ed25519_key_free"))
+
+	if (key == NULL) {
+		TRACE2(("leave ed25519_key_free: key == NULL"))
+		return;
+	}
+	m_burn(key->priv, CURVE25519_LEN);
+	m_free(key);
+
+	TRACE2(("leave ed25519_key_free"))
+}
+
+/* Put the public ed25519 key into the buffer in the required format */
+void buf_put_ed25519_pub_key(buffer *buf, const dropbear_ed25519_key *key) {
+
+	TRACE(("enter buf_put_ed25519_pub_key"))
+	dropbear_assert(key != NULL);
+
+	buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
+	buf_putstring(buf, key->pub, CURVE25519_LEN);
+
+	TRACE(("leave buf_put_ed25519_pub_key"))
+}
+
+/* Put the public and private ed25519 key into the buffer in the required format */
+void buf_put_ed25519_priv_key(buffer *buf, const dropbear_ed25519_key *key) {
+
+	TRACE(("enter buf_put_ed25519_priv_key"))
+	dropbear_assert(key != NULL);
+
+	buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
+	buf_putint(buf, CURVE25519_LEN*2);
+	buf_putbytes(buf, key->priv, CURVE25519_LEN);
+	buf_putbytes(buf, key->pub, CURVE25519_LEN);
+
+	TRACE(("leave buf_put_ed25519_priv_key"))
+}
+
+/* Sign the data presented with key, writing the signature contents
+ * to the buffer */
+void buf_put_ed25519_sign(buffer* buf, const dropbear_ed25519_key *key, const buffer *data_buf) {
+
+	unsigned char s[64];
+	unsigned long slen = sizeof(s);
+
+	TRACE(("enter buf_put_ed25519_sign"))
+	dropbear_assert(key != NULL);
+
+	dropbear_ed25519_sign(data_buf->data, data_buf->len, s, &slen, key->priv, key->pub);
+	buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
+	buf_putstring(buf, s, slen);
+
+	TRACE(("leave buf_put_ed25519_sign"))
+}
+
+#if DROPBEAR_SIGNKEY_VERIFY
+/* Verify a signature in buf, made on data by the key given.
+ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
+int buf_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const buffer *data_buf) {
+
+	int ret = DROPBEAR_FAILURE;
+	unsigned char *s;
+	unsigned long slen;
+
+	TRACE(("enter buf_ed25519_verify"))
+	dropbear_assert(key != NULL);
+
+	slen = buf_getint(buf);
+	if (slen != 64 || buf->len - buf->pos < slen) {
+		TRACE(("leave buf_ed25519_verify: bad size"))
+		goto out;
+	}
+	s = buf_getptr(buf, slen);
+
+	if (dropbear_ed25519_verify(data_buf->data, data_buf->len,
+				    s, slen, key->pub) == 0) {
+		/* signature is valid */
+		TRACE(("leave buf_ed25519_verify: success!"))
+		ret = DROPBEAR_SUCCESS;
+	}
+
+out:
+	TRACE(("leave buf_ed25519_verify: ret %d", ret))
+	return ret;
+}
+
+#endif /* DROPBEAR_SIGNKEY_VERIFY */
+
+#endif /* DROPBEAR_ED25519 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ed25519.h	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,54 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef DROPBEAR_ED25519_H_
+#define DROPBEAR_ED25519_H_
+
+#include "includes.h"
+#include "buffer.h"
+
+#if DROPBEAR_ED25519 
+
+#define CURVE25519_LEN 32
+
+typedef struct dropbear_ED25519_Key {
+
+	unsigned char priv[CURVE25519_LEN];
+	unsigned char pub[CURVE25519_LEN];
+
+} dropbear_ed25519_key;
+
+void buf_put_ed25519_sign(buffer* buf, const dropbear_ed25519_key *key, const buffer *data_buf);
+#if DROPBEAR_SIGNKEY_VERIFY
+int buf_ed25519_verify(buffer * buf, const dropbear_ed25519_key *key, const buffer *data_buf);
+#endif
+int buf_get_ed25519_pub_key(buffer* buf, dropbear_ed25519_key *key);
+int buf_get_ed25519_priv_key(buffer* buf, dropbear_ed25519_key *key);
+void buf_put_ed25519_pub_key(buffer* buf, const dropbear_ed25519_key *key);
+void buf_put_ed25519_priv_key(buffer* buf, const dropbear_ed25519_key *key);
+void ed25519_key_free(dropbear_ed25519_key *key);
+
+#endif /* DROPBEAR_ED25519 */
+
+#endif /* DROPBEAR_ED25519_H_ */
--- a/filelist.txt	Thu Mar 21 23:28:59 2019 +0800
+++ b/filelist.txt	Fri Jun 26 21:07:34 2020 +0800
@@ -99,6 +99,10 @@
 
 dss.c			DSS asymmetric crypto routines
 
+ed25519.c		Ed25519 asymmetric crypto routines
+
+gened25519.c		Ed25519 key generation
+
 gendss.c		DSS key generation
 
 genrsa.c		RSA key generation
--- a/fuzz-common.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/fuzz-common.c	Fri Jun 26 21:07:34 2020 +0800
@@ -112,6 +112,14 @@
         dropbear_exit("failed fixed ecdsa hostkey");
     }
 
+    buf_setlen(b, 0);
+    buf_putbytes(b, keyed25519, keyed25519_len);
+    buf_setpos(b, 0);
+    type = DROPBEAR_SIGNKEY_ED25519;
+    if (buf_get_priv_key(b, svr_opts.hostkey, &type) == DROPBEAR_FAILURE) {
+        dropbear_exit("failed fixed ed25519 hostkey");
+    }
+
     buf_free(b);
 }
 
@@ -139,7 +147,7 @@
 void fuzz_fake_send_kexdh_reply(void) {
     assert(!ses.dh_K);
     m_mp_alloc_init_multi(&ses.dh_K, NULL);
-    mp_set_int(ses.dh_K, 12345678);
+    mp_set_ul(ses.dh_K, 12345678uL);
     finish_kexhashbuf();
 }
 
--- a/fuzz-hostkeys.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/fuzz-hostkeys.c	Fri Jun 26 21:07:34 2020 +0800
@@ -127,3 +127,13 @@
   0xf9, 0x39
 };
 unsigned int keyd_len = 458;
+unsigned char keyed25519[] = {
+  0x00, 0x00, 0x00, 0x0b, 0x73, 0x73, 0x68, 0x2d, 0x65, 0x64, 0x32, 0x35,
+  0x35, 0x31, 0x39, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb3, 0x79, 0x06, 0xe5,
+  0x9b, 0xe7, 0xe4, 0x6e, 0xec, 0xfe, 0xa5, 0x39, 0x21, 0x7c, 0xf6, 0x66,
+  0x8c, 0x0b, 0x6a, 0x01, 0x09, 0x05, 0xc7, 0x4f, 0x64, 0xa8, 0x24, 0xd2,
+  0x8d, 0xbd, 0xdd, 0xc6, 0x3c, 0x99, 0x1b, 0x2d, 0x3e, 0x33, 0x90, 0x19,
+  0xa4, 0xd5, 0xe9, 0x23, 0xfe, 0x8e, 0xd6, 0xd4, 0xf9, 0xb1, 0x11, 0x69,
+  0x7c, 0x57, 0x52, 0x0e, 0x41, 0xdb, 0x1b, 0x12, 0x87, 0xfa, 0xc9
+};
+unsigned int keyed25519_len = 83;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fuzzer-kexcurve25519.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,72 @@
+#include "fuzz.h"
+#include "session.h"
+#include "fuzz-wrapfd.h"
+#include "debug.h"
+#include "runopts.h"
+#include "algo.h"
+#include "bignum.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+	static int once = 0;
+	static struct key_context* keep_newkeys = NULL;
+	/* number of generated parameters is limited by the timeout for the first run.
+	   TODO move this to the libfuzzer initialiser function instead if the timeout
+	   doesn't apply there */
+	#define NUM_PARAMS 20
+	static struct kex_curve25519_param *curve25519_params[NUM_PARAMS];
+
+	if (!once) {
+		fuzz_common_setup();
+		fuzz_svr_setup();
+
+		keep_newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
+		keep_newkeys->algo_kex = fuzz_get_algo(sshkex, "curve25519-sha256");
+		keep_newkeys->algo_hostkey = DROPBEAR_SIGNKEY_ED25519;
+		ses.newkeys = keep_newkeys;
+
+		/* Pre-generate parameters */
+		int i;
+		for (i = 0; i < NUM_PARAMS; i++) {
+			curve25519_params[i] = gen_kexcurve25519_param();
+		}
+
+		once = 1;
+	}
+
+	if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
+		return 0;
+	}
+
+	m_malloc_set_epoch(1);
+
+	if (setjmp(fuzz.jmp) == 0) {
+		/* Based on recv_msg_kexdh_init()/send_msg_kexdh_reply() 
+		with DROPBEAR_KEX_CURVE25519 */
+		ses.newkeys = keep_newkeys;
+
+		/* Choose from the collection of curve25519 params */
+		unsigned int e = buf_getint(fuzz.input);
+		struct kex_curve25519_param *curve25519_param = curve25519_params[e % NUM_PARAMS];
+
+		buffer * ecdh_qs = buf_getstringbuf(fuzz.input);
+
+		ses.kexhashbuf = buf_new(KEXHASHBUF_MAX_INTS);
+		kexcurve25519_comb_key(curve25519_param, ecdh_qs, svr_opts.hostkey);
+
+		mp_clear(ses.dh_K);
+		m_free(ses.dh_K);
+		buf_free(ecdh_qs);
+
+		buf_free(ses.hash);
+		buf_free(ses.session_id);
+		/* kexhashbuf is freed in kexdh_comb_key */
+
+		m_malloc_free_epoch(1, 0);
+	} else {
+		m_malloc_free_epoch(1, 1);
+		TRACE(("dropbear_exit longjmped"))
+		/* dropbear_exit jumped here */
+	}
+
+	return 0;
+}
--- a/fuzzer-pubkey.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/fuzzer-pubkey.c	Fri Jun 26 21:07:34 2020 +0800
@@ -27,7 +27,7 @@
 		unsigned int algolen;
 		char* algoname = buf_getstring(keyblob, &algolen);
 
-		if (have_algo(algoname, algolen, sshhostkey) == DROPBEAR_FAILURE) {
+		if (signature_type_from_name(algoname, algolen) == DROPBEAR_SIGNKEY_NONE) {
 			dropbear_exit("fuzzer imagined a bogus algorithm");
 		}
 
--- a/fuzzer-verify.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/fuzzer-verify.c	Fri Jun 26 21:07:34 2020 +0800
@@ -2,6 +2,7 @@
 #include "session.h"
 #include "fuzz-wrapfd.h"
 #include "debug.h"
+#include "dss.h"
 
 static void setup_fuzzer(void) {
 	fuzz_common_setup();
@@ -27,21 +28,35 @@
 
 	if (setjmp(fuzz.jmp) == 0) {
 		sign_key *key = new_sign_key();
-		enum signkey_type type = DROPBEAR_SIGNKEY_ANY;
-		if (buf_get_pub_key(fuzz.input, key, &type) == DROPBEAR_SUCCESS) {
-			if (buf_verify(fuzz.input, key, verifydata) == DROPBEAR_SUCCESS) {
+		enum signkey_type keytype = DROPBEAR_SIGNKEY_ANY;
+		if (buf_get_pub_key(fuzz.input, key, &keytype) == DROPBEAR_SUCCESS) {
+			enum signature_type sigtype;
+			if (keytype == DROPBEAR_SIGNKEY_RSA) {
+				/* Flip a coin to decide rsa signature type */
+				int flag = buf_getbyte(fuzz.input);
+				if (flag & 0x01) {
+					sigtype = DROPBEAR_SIGNATURE_RSA_SHA256;
+				} else {
+					sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
+				}
+			} else {
+				sigtype = signature_type_from_signkey(keytype);
+			}
+			if (buf_verify(fuzz.input, key, sigtype, verifydata) == DROPBEAR_SUCCESS) {
 				/* The fuzzer is capable of generating keys with a signature to match.
 				We don't want false positives if the key is bogus, since a client/server 
 				wouldn't be trusting a bogus key anyway */
 				int boguskey = 0;
 
-				if (type == DROPBEAR_SIGNKEY_DSS) {
+				if (keytype == DROPBEAR_SIGNKEY_DSS) {
 					/* So far have seen dss keys with bad p/q/g domain parameters */
-					int pprime, qprime;
-				    assert(mp_prime_is_prime(key->dsskey->p, 5, &pprime) == MP_OKAY);
-				    assert(mp_prime_is_prime(key->dsskey->q, 18, &qprime) == MP_OKAY);
-				    boguskey = !(pprime && qprime);
-				    /* Could also check g**q mod p == 1 */
+					int pprime, qprime, trials;
+					trials = mp_prime_rabin_miller_trials(mp_count_bits(key->dsskey->p));
+					assert(mp_prime_is_prime(key->dsskey->p, trials, &pprime) == MP_OKAY);
+					trials = mp_prime_rabin_miller_trials(mp_count_bits(key->dsskey->q));
+					assert(mp_prime_is_prime(key->dsskey->q, trials, &qprime) == MP_OKAY);
+					boguskey = !(pprime && qprime);
+					/* Could also check g**q mod p == 1 */
 				}
 
 				if (!boguskey) {
--- a/fuzzers_test.sh	Thu Mar 21 23:28:59 2019 +0800
+++ b/fuzzers_test.sh	Fri Jun 26 21:07:34 2020 +0800
@@ -4,7 +4,7 @@
 
 result=0
 
-hg clone https://secure.ucc.asn.au/hg/dropbear-fuzzcorpus fuzzcorpus || exit 1
+test -d fuzzcorpus && hg --repository fuzzcorpus/ pull || hg clone https://secure.ucc.asn.au/hg/dropbear-fuzzcorpus fuzzcorpus || exit 1
 for f in `make list-fuzz-targets`; do
     ./$f fuzzcorpus/$f/* || result=1
 done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcm.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,120 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * Copyright (c) 2020 by Vladislav Grishenko
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "algo.h"
+#include "dbutil.h"
+#include "gcm.h"
+
+#if DROPBEAR_ENABLE_GCM_MODE
+
+#define GHASH_LEN 16
+
+static const struct dropbear_hash dropbear_ghash =
+	{NULL, 0, GHASH_LEN};
+
+static int dropbear_gcm_start(int cipher, const unsigned char *IV,
+			const unsigned char *key, int keylen,
+			int UNUSED(num_rounds), dropbear_gcm_state *state) {
+	int err;
+
+	TRACE2(("enter dropbear_gcm_start"))
+
+	if ((err = gcm_init(&state->gcm, cipher, key, keylen)) != CRYPT_OK) {
+		return err;
+	}
+	memcpy(state->iv, IV, GCM_NONCE_LEN);
+
+	TRACE2(("leave dropbear_gcm_start"))
+	return CRYPT_OK;
+}
+
+static int dropbear_gcm_crypt(unsigned int UNUSED(seq),
+			const unsigned char *in, unsigned char *out,
+			unsigned long len, unsigned long taglen,
+			dropbear_gcm_state *state, int direction) {
+	unsigned char *iv, tag[GHASH_LEN];
+	int i, err;
+
+	TRACE2(("enter dropbear_gcm_crypt"))
+
+	if (len < 4 || taglen != GHASH_LEN) {
+		return CRYPT_ERROR;
+	}
+
+	gcm_reset(&state->gcm);
+
+	if ((err = gcm_add_iv(&state->gcm,
+				state->iv, GCM_NONCE_LEN)) != CRYPT_OK) {
+		return err;
+	}
+
+	if ((err = gcm_add_aad(&state->gcm, in, 4)) != CRYPT_OK) {
+		return err;
+	}
+
+	if ((err = gcm_process(&state->gcm, (unsigned char *) in + 4,
+				len - 4, out + 4, direction)) != CRYPT_OK) {
+		return err;
+	}
+
+	if (direction == LTC_ENCRYPT) {
+		gcm_done(&state->gcm, out + len, &taglen);
+	} else {
+		gcm_done(&state->gcm, tag, &taglen);
+		if (constant_time_memcmp(in + len, tag, taglen) != 0) {
+			return CRYPT_ERROR;
+		}
+	}
+
+	/* increment invocation counter */
+	iv = state->iv + GCM_IVFIX_LEN;
+	for (i = GCM_IVCTR_LEN - 1; i >= 0 && ++iv[i] == 0; i--);
+
+	TRACE2(("leave dropbear_gcm_crypt"))
+	return CRYPT_OK;
+}
+
+static int dropbear_gcm_getlength(unsigned int UNUSED(seq),
+			const unsigned char *in, unsigned int *outlen,
+			unsigned long len, dropbear_gcm_state* UNUSED(state)) {
+	TRACE2(("enter dropbear_gcm_getlength"))
+
+	if (len < 4) {
+		return CRYPT_ERROR;
+	}
+
+	LOAD32H(*outlen, in);
+
+	TRACE2(("leave dropbear_gcm_getlength"))
+	return CRYPT_OK;
+}
+
+const struct dropbear_cipher_mode dropbear_mode_gcm =
+	{(void *)dropbear_gcm_start, NULL, NULL,
+	 (void *)dropbear_gcm_crypt,
+	 (void *)dropbear_gcm_getlength, &dropbear_ghash};
+
+#endif /* DROPBEAR_ENABLE_GCM_MODE */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcm.h	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,47 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * Copyright (c) 2020 by Vladislav Grishenko
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef DROPBEAR_DROPBEAR_GCM_H_
+#define DROPBEAR_DROPBEAR_GCM_H_
+
+#include "includes.h"
+#include "algo.h"
+
+#if DROPBEAR_ENABLE_GCM_MODE
+
+#define GCM_IVFIX_LEN 4
+#define GCM_IVCTR_LEN 8
+#define GCM_NONCE_LEN (GCM_IVFIX_LEN + GCM_IVCTR_LEN)
+
+typedef struct {
+	gcm_state gcm;
+	unsigned char iv[GCM_NONCE_LEN];
+} dropbear_gcm_state;
+
+extern const struct dropbear_cipher_mode dropbear_mode_gcm;
+
+#endif /* DROPBEAR_ENABLE_GCM_MODE */
+
+#endif /* DROPBEAR_DROPBEAR_GCM_H_ */
--- a/gendss.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/gendss.c	Fri Jun 26 21:07:34 2020 +0800
@@ -68,6 +68,7 @@
 static void getq(const dropbear_dss_key *key) {
 
 	unsigned char buf[QSIZE];
+	int trials;
 
 	/* 160 bit prime */
 	genrandom(buf, QSIZE);
@@ -76,8 +77,9 @@
 
 	bytes_to_mp(key->q, buf, QSIZE);
 
-	/* 18 rounds are required according to HAC */
-	if (mp_prime_next_prime(key->q, 18, 0) != MP_OKAY) {
+	/* ask FIPS 186.4 how many Rabin-Miller trials are required */
+	trials = mp_prime_rabin_miller_trials(mp_count_bits(key->q));
+	if (mp_prime_next_prime(key->q, trials, 0) != MP_OKAY) {
 		fprintf(stderr, "DSS key generation failed\n");
 		exit(1);
 	}
@@ -89,7 +91,7 @@
 	DEF_MP_INT(tempC);
 	DEF_MP_INT(tempP);
 	DEF_MP_INT(temp2q);
-	int result;
+	int result, trials;
 	unsigned char *buf;
 
 	m_mp_init_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
@@ -129,9 +131,10 @@
 			exit(1);
 		}
 
-		/* now check for prime, 5 rounds is enough according to HAC */
+		/* ask FIPS 186.4 how many Rabin-Miller trials are required */
+		trials = mp_prime_rabin_miller_trials(mp_count_bits(key->p));
 		/* result == 1  =>  p is prime */
-		if (mp_prime_is_prime(key->p, 5, &result) != MP_OKAY) {
+		if (mp_prime_is_prime(key->p, trials, &result) != MP_OKAY) {
 			fprintf(stderr, "DSS key generation failed\n");
 			exit(1);
 		}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gened25519.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,47 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "dbutil.h"
+#include "dbrandom.h"
+#include "curve25519.h"
+#include "gened25519.h"
+
+#if DROPBEAR_ED25519
+
+dropbear_ed25519_key * gen_ed25519_priv_key(unsigned int size) {
+
+	dropbear_ed25519_key *key;
+
+	if (size != 256) {
+		dropbear_exit("Ed25519 keys have a fixed size of 256 bits");
+	}
+
+	key = m_malloc(sizeof(*key));
+	dropbear_ed25519_make_key(key->pub, key->priv);
+
+	return key;
+}
+
+#endif /* DROPBEAR_ED25519 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gened25519.h	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,36 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef DROPBEAR_GENED25519_H_
+#define DROPBEAR_GENED25519_H_
+
+#include "ed25519.h"
+
+#if DROPBEAR_ED25519
+
+dropbear_ed25519_key * gen_ed25519_priv_key(unsigned int size);
+
+#endif /* DROPBEAR_ED25519 */
+
+#endif /* DROPBEAR_GENED25519_H_ */
--- a/genrsa.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/genrsa.c	Fri Jun 26 21:07:34 2020 +0800
@@ -53,10 +53,7 @@
 	m_mp_alloc_init_multi(&key->e, &key->n, &key->d, &key->p, &key->q, NULL);
 	m_mp_init_multi(&pminus, &lcm, &qminus, NULL);
 
-	if (mp_set_int(key->e, RSA_E) != MP_OKAY) {
-		fprintf(stderr, "RSA generation failed\n");
-		exit(1);
-	}
+	mp_set_ul(key->e, RSA_E);
 
 	while (1) {
 		getrsaprime(key->p, &pminus, key->e, size/16);
@@ -95,6 +92,7 @@
 		mp_int* rsa_e, unsigned int size_bytes) {
 
 	unsigned char *buf;
+	int trials;
 	DEF_MP_INT(temp_gcd);
 
 	buf = (unsigned char*)m_malloc(size_bytes);
@@ -108,8 +106,9 @@
 
 		bytes_to_mp(prime, buf, size_bytes);
 
-		/* find the next integer which is prime, 8 round of miller-rabin */
-		if (mp_prime_next_prime(prime, 8, 0) != MP_OKAY) {
+		/* find the next integer which is prime */
+		trials = mp_prime_rabin_miller_trials(mp_count_bits(prime));
+		if (mp_prime_next_prime(prime, trials, 0) != MP_OKAY) {
 			fprintf(stderr, "RSA generation failed\n");
 			exit(1);
 		}
--- a/gensignkey.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/gensignkey.c	Fri Jun 26 21:07:34 2020 +0800
@@ -4,18 +4,26 @@
 #include "ecdsa.h"
 #include "genrsa.h"
 #include "gendss.h"
+#include "gened25519.h"
 #include "signkey.h"
 #include "dbrandom.h"
 
 /* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
-static int buf_writefile(buffer * buf, const char * filename) {
+static int buf_writefile(buffer * buf, const char * filename, int skip_exist) {
 	int ret = DROPBEAR_FAILURE;
 	int fd = -1;
 
 	fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
 	if (fd < 0) {
-		dropbear_log(LOG_ERR, "Couldn't create new file %s: %s",
-			filename, strerror(errno));
+		/* If generating keys on connection (skip_exist) it's OK to get EEXIST
+		- we probably just lost a race with another connection to generate the key */
+		if (skip_exist && errno == EEXIST) {
+			ret = DROPBEAR_SUCCESS;
+		} else {
+			dropbear_log(LOG_ERR, "Couldn't create new file %s: %s",
+				filename, strerror(errno));
+		}
+
 		goto out;
 	}
 
@@ -69,6 +77,10 @@
 		case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
 			return 256;
 #endif
+#if DROPBEAR_ED25519
+		case DROPBEAR_SIGNKEY_ED25519:
+			return 256;
+#endif
 		default:
 			return 0;
 	}
@@ -119,6 +131,11 @@
 			}
 			break;
 #endif
+#if DROPBEAR_ED25519
+		case DROPBEAR_SIGNKEY_ED25519:
+			key->ed25519key = gen_ed25519_priv_key(bits);
+			break;
+#endif
 		default:
 			dropbear_exit("Internal error");
 	}
@@ -134,7 +151,7 @@
 
 	fn_temp = m_malloc(strlen(filename) + 30);
 	snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid());
-	ret = buf_writefile(buf, fn_temp);
+	ret = buf_writefile(buf, fn_temp, 0);
 
 	if (ret == DROPBEAR_FAILURE) {
 		goto out;
@@ -144,14 +161,24 @@
 		/* If generating keys on connection (skipexist) it's OK to get EEXIST 
 		- we probably just lost a race with another connection to generate the key */
 		if (!(skip_exist && errno == EEXIST)) {
-			dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename,
-				strerror(errno));
-			/* XXX fallback to non-atomic copy for some filesystems? */
-			ret = DROPBEAR_FAILURE;
+			if (errno == EPERM || errno == EACCES) {
+				/* Non-atomic fallback when hard-links not allowed or unsupported */
+				buf_setpos(buf, 0);
+				ret = buf_writefile(buf, filename, skip_exist);
+			} else {
+				dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename,
+					strerror(errno));
+				ret = DROPBEAR_FAILURE;
+			}
+
 			goto out;
 		}
 	}
 
+	/* ensure directory update is flushed to disk, otherwise we can end up
+	with zero-byte hostkey files if the power goes off */
+	fsync_parent_dir(filename);
+
 out:
 	if (buf) {
 		buf_burn(buf);
--- a/includes.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/includes.h	Fri Jun 26 21:07:34 2020 +0800
@@ -25,6 +25,8 @@
 #ifndef DROPBEAR_INCLUDES_H_
 #define DROPBEAR_INCLUDES_H_
 
+/* uclibc needs _GNU_SOURCE, maybe other things? */
+#define _GNU_SOURCE
 
 #include "options.h"
 #include "debug.h"
@@ -124,6 +126,10 @@
 #include <sys/uio.h>
 #endif
 
+#ifdef HAVE_SYS_RANDOM_H
+#include <sys/random.h>
+#endif
+
 #ifdef BUNDLED_LIBTOM
 #include "libtomcrypt/src/headers/tomcrypt.h"
 #include "libtommath/tommath.h"
@@ -164,6 +170,10 @@
 #include <linux/pkt_sched.h>
 #endif
 
+#if DROPBEAR_PLUGIN
+#include <dlfcn.h>
+#endif
+
 #include "fake-rfc2553.h"
 
 #include "fuzz.h"
--- a/kex.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/kex.h	Fri Jun 26 21:07:34 2020 +0800
@@ -36,10 +36,12 @@
 void kexfirstinitialise(void);
 void finish_kexhashbuf(void);
 
+#if DROPBEAR_NORMAL_DH
 struct kex_dh_param *gen_kexdh_param(void);
 void free_kexdh_param(struct kex_dh_param *param);
 void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them,
 		sign_key *hostkey);
+#endif
 
 #if DROPBEAR_ECDH
 struct kex_ecdh_param *gen_kexecdh_param(void);
@@ -65,6 +67,8 @@
 void send_msg_kexdh_init(void); /* client */
 void recv_msg_kexdh_reply(void); /* client */
 
+void recv_msg_ext_info(void);
+
 struct KEXState {
 
 	unsigned sentkexinit : 1; /*set when we've sent/recv kexinit packet */
@@ -73,8 +77,9 @@
 	unsigned sentnewkeys : 1; /* set once we've send MSG_NEWKEYS (will be cleared once we have also received */
 	unsigned recvnewkeys : 1; /* set once we've received MSG_NEWKEYS (cleared once we have also sent */
 
-	unsigned donefirstkex : 1; /* Set to 1 after the first kex has completed,
+	unsigned int donefirstkex; /* Set to 1 after the first kex has completed,
 								  ie the transport layer has been set up */
+	unsigned int donesecondkex; /* Set to 1 after the second kex has completed */
 
 	unsigned our_first_follows_matches : 1;
 
@@ -84,10 +89,12 @@
 
 };
 
+#if DROPBEAR_NORMAL_DH
 struct kex_dh_param {
 	mp_int pub; /* e */
 	mp_int priv; /* x */
 };
+#endif
 
 #if DROPBEAR_ECDH
 struct kex_ecdh_param {
@@ -101,9 +108,6 @@
 	unsigned char priv[CURVE25519_LEN];
 	unsigned char pub[CURVE25519_LEN];
 };
-
-/* No header file for curve25519_donna */
-int curve25519_donna(unsigned char *out, const unsigned char *secret, const unsigned char *other);
 #endif
 
 #endif /* DROPBEAR_KEX_H_ */
--- a/keyimport.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/keyimport.c	Fri Jun 26 21:07:34 2020 +0800
@@ -35,6 +35,18 @@
 #include "buffer.h"
 #include "dbutil.h"
 #include "ecc.h"
+#include "ssh.h"
+#include "rsa.h"
+#include "dss.h"
+#include "ed25519.h"
+
+static const unsigned char OSSH_PKEY_BLOB[] =
+	"openssh-key-v1\0"			/* AUTH_MAGIC */
+	"\0\0\0\4none"				/* cipher name*/
+	"\0\0\0\4none"				/* kdf name */
+	"\0\0\0\0"				/* kdf */
+	"\0\0\0\1";				/* key num */
+#define OSSH_PKEY_BLOBLEN (sizeof(OSSH_PKEY_BLOB) - 1)
 
 #if DROPBEAR_ECDSA
 static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
@@ -352,7 +364,7 @@
  * Code to read and write OpenSSH private keys.
  */
 
-enum { OSSH_DSA, OSSH_RSA, OSSH_EC };
+enum { OSSH_DSA, OSSH_RSA, OSSH_EC, OSSH_PKEY };
 struct openssh_key {
 	int type;
 	int encrypted;
@@ -364,11 +376,12 @@
 static struct openssh_key *load_openssh_key(const char *filename)
 {
 	struct openssh_key *ret;
+	buffer *buf = NULL;
 	FILE *fp = NULL;
 	char buffer[256];
 	char *errmsg = NULL, *p = NULL;
 	int headers_done;
-	unsigned long len, outlen;
+	unsigned long len;
 
 	ret = (struct openssh_key*)m_malloc(sizeof(struct openssh_key));
 	ret->keyblob = NULL;
@@ -397,12 +410,15 @@
 		ret->type = OSSH_DSA;
 	else if (!strcmp(buffer, "-----BEGIN EC PRIVATE KEY-----\n"))
 		ret->type = OSSH_EC;
+	else if (!strcmp(buffer, "-----BEGIN OPENSSH PRIVATE KEY-----\n"))
+		ret->type = OSSH_PKEY;
 	else {
 		errmsg = "Unrecognised key type";
 		goto error;
 	}
 
 	headers_done = 0;
+	buf = buf_new(0);
 	while (1) {
 		if (!fgets(buffer, sizeof(buffer), fp)) {
 			errmsg = "Unexpected end of file";
@@ -448,22 +464,33 @@
 		} else {
 			headers_done = 1;
 			len = strlen(buffer);
-			outlen = len*4/3;
-			if (ret->keyblob_len + outlen > ret->keyblob_size) {
-				ret->keyblob_size = ret->keyblob_len + outlen + 256;
-				ret->keyblob = (unsigned char*)m_realloc(ret->keyblob,
-						ret->keyblob_size);
-			}
-			outlen = ret->keyblob_size - ret->keyblob_len;
-			if (base64_decode((const unsigned char *)buffer, len,
-						ret->keyblob + ret->keyblob_len, &outlen) != CRYPT_OK){
-				errmsg = "Error decoding base64";
-				goto error;
-			}
-			ret->keyblob_len += outlen;
+			buf = buf_resize(buf, buf->size + len);
+			buf_putbytes(buf, buffer, len);
 		}
 	}
 
+	if (buf && buf->len) {
+		ret->keyblob_size = ret->keyblob_len + buf->len*4/3 + 256;
+		ret->keyblob = (unsigned char*)m_realloc(ret->keyblob, ret->keyblob_size);
+		len = ret->keyblob_size;
+		if (base64_decode((const unsigned char *)buf->data, buf->len,
+					ret->keyblob, &len) != CRYPT_OK){
+			errmsg = "Error decoding base64";
+			goto error;
+		}
+		ret->keyblob_len = len;
+	}
+
+	if (ret->type == OSSH_PKEY) {
+		if (ret->keyblob_len < OSSH_PKEY_BLOBLEN ||
+				memcmp(ret->keyblob, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN)) {
+			errmsg = "Error decoding OpenSSH key";
+			goto error;
+		}
+		ret->keyblob_len -= OSSH_PKEY_BLOBLEN;
+		memmove(ret->keyblob, ret->keyblob + OSSH_PKEY_BLOBLEN, ret->keyblob_len);
+	}
+
 	if (ret->keyblob_len == 0 || !ret->keyblob) {
 		errmsg = "Key body not present";
 		goto error;
@@ -474,10 +501,18 @@
 		goto error;
 	}
 
+	if (buf) {
+		buf_burn(buf);
+		buf_free(buf);
+	}
 	m_burn(buffer, sizeof(buffer));
 	return ret;
 
 error:
+	if (buf) {
+		buf_burn(buf);
+		buf_free(buf);
+	}
 	m_burn(buffer, sizeof(buffer));
 	if (ret) {
 		if (ret->keyblob) {
@@ -570,6 +605,57 @@
 	}
 
 	/*
+	 * Now we have a decrypted key blob, which contains OpenSSH
+	 * encoded private key. We must now untangle the OpenSSH format.
+	 */
+	if (key->type == OSSH_PKEY) {
+		blobbuf = buf_new(key->keyblob_len);
+		buf_putbytes(blobbuf, key->keyblob, key->keyblob_len);
+		buf_setpos(blobbuf, 0);
+
+		/* limit length of private key blob */
+		len = buf_getint(blobbuf);
+		buf_setlen(blobbuf, blobbuf->pos + len);
+
+		type = DROPBEAR_SIGNKEY_ANY;
+		if (buf_get_pub_key(blobbuf, retkey, &type)
+				!= DROPBEAR_SUCCESS) {
+			errmsg = "Error parsing OpenSSH key";
+			goto ossh_error;
+		}
+
+		/* restore full length */
+		buf_setlen(blobbuf, key->keyblob_len);
+
+		if (type != DROPBEAR_SIGNKEY_NONE) {
+			retkey->type = type;
+			/* limit length of private key blob */
+			len = buf_getint(blobbuf);
+			buf_setlen(blobbuf, blobbuf->pos + len);
+#if DROPBEAR_ED25519
+			if (type == DROPBEAR_SIGNKEY_ED25519) {
+				buf_incrpos(blobbuf, 8);
+				buf_eatstring(blobbuf);
+				buf_eatstring(blobbuf);
+				buf_incrpos(blobbuf, -SSH_SIGNKEY_ED25519_LEN-4);
+				if (buf_get_ed25519_priv_key(blobbuf, retkey->ed25519key)
+						== DROPBEAR_SUCCESS) {
+					errmsg = NULL;
+					retval = retkey;
+					goto error;
+				}
+			}
+#endif
+		}
+
+		errmsg = "Unsupported OpenSSH key type";
+		ossh_error:
+		sign_key_free(retkey);
+		retkey = NULL;
+		goto error;
+	}
+
+	/*
 	 * Now we have a decrypted key blob, which contains an ASN.1
 	 * encoded private key. We must now untangle the ASN.1.
 	 *
@@ -781,7 +867,7 @@
 			goto error;
 		}
 		m_mp_alloc_init_multi((mp_int**)&ecc->k, NULL);
-		if (mp_read_unsigned_bin(ecc->k, private_key_bytes, private_key_len)
+		if (mp_from_ubin(ecc->k, private_key_bytes, private_key_len)
 			!= MP_OKAY) {
 			errmsg = "Error parsing ECC key";
 			goto error;
@@ -1056,6 +1142,7 @@
 		unsigned long pubkey_size = 2*curve_size+1;
 		int k_size;
 		int err = 0;
+		size_t written;
 
 		/* version. less than 10 bytes */
 		buf_incrwritepos(seq_buf,
@@ -1063,12 +1150,14 @@
 		buf_putbyte(seq_buf, 1);
 
 		/* privateKey */
-		k_size = mp_unsigned_bin_size((*eck)->k);
+		k_size = mp_ubin_size((*eck)->k);
 		dropbear_assert(k_size <= curve_size);
 		buf_incrwritepos(seq_buf,
 			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, k_size, 0));
-		mp_to_unsigned_bin((*eck)->k, buf_getwriteptr(seq_buf, k_size));
-		buf_incrwritepos(seq_buf, k_size);
+		if (mp_to_ubin((*eck)->k, buf_getwriteptr(seq_buf, k_size), k_size, &written) != MP_OKAY) {
+			dropbear_exit("ECC error");
+		}
+		buf_incrwritepos(seq_buf, written);
 
 		/* SECGCurveNames */
 		switch (key->type)
@@ -1129,6 +1218,51 @@
 	}
 #endif
 
+#if DROPBEAR_ED25519
+	if (key->type == DROPBEAR_SIGNKEY_ED25519) {
+		buffer *buf = buf_new(300);
+		keyblob = buf_new(100);
+		extrablob = buf_new(200);
+
+		/* private key blob w/o header */
+		buf_put_priv_key(keyblob, key, key->type);
+		buf_setpos(keyblob, 0);
+		buf_incrpos(keyblob, buf_getint(keyblob));
+		len = buf_getint(keyblob);
+
+		/* header */
+		buf_putbytes(buf, OSSH_PKEY_BLOB, OSSH_PKEY_BLOBLEN);
+
+		/* public key */
+		buf_put_pub_key(buf, key, key->type);
+
+		/* private key */
+		buf_incrwritepos(extrablob, 4);
+		buf_put_pub_key(extrablob, key, key->type);
+		buf_putstring(extrablob, buf_getptr(keyblob, len), len);
+		/* comment */
+		buf_putstring(extrablob, "", 0);
+		/* padding to cipher block length */
+		len = (extrablob->len+8) & ~7;
+		for (i = 1; len - extrablob->len > 0; i++)
+			buf_putbyte(extrablob, i);
+		buf_setpos(extrablob, 0);
+		buf_putbytes(extrablob, "\0\0\0\0\0\0\0\0", 8);
+		buf_putbufstring(buf, extrablob);
+
+		outlen = len = pos = buf->len;
+		outblob = (unsigned char*)m_malloc(outlen);
+		memcpy(outblob, buf->data, buf->len);
+
+		buf_burn(buf);
+		buf_free(buf);
+		buf = NULL;
+
+		header = "-----BEGIN OPENSSH PRIVATE KEY-----\n";
+		footer = "-----END OPENSSH PRIVATE KEY-----\n";
+	}
+#endif
+
 	/*
 	 * Padding on OpenSSH keys is deterministic. The number of
 	 * padding bytes is always more than zero, and always at most
--- a/libtomcrypt/changes	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/changes	Fri Jun 26 21:07:34 2020 +0800
@@ -1,3 +1,16 @@
+July 1st, 2018
+v1.18.2
+      -- Fix Side Channel Based ECDSA Key Extraction (CVE-2018-12437) (PR #408)
+      -- Fix potential stack overflow when DER flexi-decoding (CVE-2018-0739) (PR #373)
+      -- Fix two-key 3DES (PR #390)
+      -- Fix accelerated CTR mode (PR #359)
+      -- Fix Fortuna PRNG (PR #363)
+      -- Fix compilation on platforms where cc doesn't point to gcc (PR #382)
+      -- Fix using the wrong environment variable LT instead of LIBTOOL (PR #392)
+      -- Fix build on platforms where the compiler provides __WCHAR_MAX__ but wchar.h is not available (PR #390)
+      -- Fix & re-factor crypt_list_all_sizes() and crypt_list_all_constants() (PR #414)
+      -- Minor fixes (PR's #350 #351 #375 #377 #378 #379)
+
 January 22nd, 2018
 v1.18.1
       -- Fix wrong SHA3 blocksizes, thanks to Claus Fischer for reporting this via Mail (PR #329)
--- a/libtomcrypt/demos/constants.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/demos/constants.c	Fri Jun 26 21:07:34 2020 +0800
@@ -65,9 +65,10 @@
          /* get and print the length of the names (and values) list */
          if (crypt_list_all_constants(NULL, &names_list_len) != 0) exit(EXIT_FAILURE);
          /* get and print the names (and values) list */
-         names_list = malloc(names_list_len);
+         if ((names_list = malloc(names_list_len)) == NULL) exit(EXIT_FAILURE);
          if (crypt_list_all_constants(names_list, &names_list_len) != 0) exit(EXIT_FAILURE);
          printf("%s\n", names_list);
+         free(names_list);
       }
    } else if (argc == 3) {
       if (strcmp(argv[1], "-s") == 0) {
--- a/libtomcrypt/demos/sizes.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/demos/sizes.c	Fri Jun 26 21:07:34 2020 +0800
@@ -42,9 +42,10 @@
       printf("  need to allocate %u bytes \n\n", sizes_list_len);
 
       /* get and print the names (and sizes) list */
-      sizes_list = malloc(sizes_list_len);
+      if ((sizes_list = malloc(sizes_list_len)) == NULL) exit(EXIT_FAILURE);
       if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE);
       printf("  supported sizes:\n\n%s\n\n", sizes_list);
+      free(sizes_list);
    } else if (argc == 2) {
       if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
          char* base = strdup(basename(argv[0]));
@@ -60,9 +61,10 @@
          /* get and print the length of the names (and sizes) list */
          if (crypt_list_all_sizes(NULL, &sizes_list_len) != 0) exit(EXIT_FAILURE);
          /* get and print the names (and sizes) list */
-         sizes_list = malloc(sizes_list_len);
+         if ((sizes_list = malloc(sizes_list_len)) == NULL) exit(EXIT_FAILURE);
          if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE);
          printf("%s\n", sizes_list);
+         free(sizes_list);
       }
    } else if (argc == 3) {
       if (strcmp(argv[1], "-s") == 0) {
--- a/libtomcrypt/demos/timing.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/demos/timing.c	Fri Jun 26 21:07:34 2020 +0800
@@ -466,7 +466,7 @@
    tally_results(1);
 }
 #else
-static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); return 0; }
+static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); }
 #endif
 
 
--- a/libtomcrypt/demos/tv_gen.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/demos/tv_gen.c	Fri Jun 26 21:07:34 2020 +0800
@@ -78,7 +78,7 @@
             printf("keysize error: %s\n", error_to_string(err));
             exit(EXIT_FAILURE);
          }
-         if (kl == lastkl) break;
+         if (kl == lastkl) continue;
          lastkl = kl;
          fprintf(out, "Key Size: %d bytes\n", kl);
 
--- a/libtomcrypt/doc/Doxyfile	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/doc/Doxyfile	Fri Jun 26 21:07:34 2020 +0800
@@ -38,7 +38,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER=1.18.1
+PROJECT_NUMBER=1.18.2
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
--- a/libtomcrypt/doc/crypt.tex	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/doc/crypt.tex	Fri Jun 26 21:07:34 2020 +0800
@@ -3666,11 +3666,15 @@
 it has been fixed to those choices.
 
 Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being
-added to the PRNG learn far less about the state than that of Yarrow.  Without getting into to many
+added to the PRNG learn far less about the state than that of Yarrow.  Without getting into too many
 details Fortuna has the ability to recover from state determination attacks where the attacker starts
 to learn information from the PRNGs output about the internal state.  Yarrow on the other hand, cannot
 recover from that problem until new entropy is added to the pool and put to use through the ready() function.
 
+For detailed information on how the algorithm works and what you have to do to maintain the secure state
+get a copy of the book\footnote{Niels Ferguson and Bruce Schneier, Practical Cryptography. ISBN 0-471-22357-3.} or
+read the paper online\footnote{\url{https://www.schneier.com/academic/paperfiles/fortuna.pdf} [Accessed on 7th Dec. 2017]}.
+
 \subsubsection{RC4}
 
 RC4 is an old stream cipher that can also double duty as a PRNG in a pinch.  You key RC4 by
--- a/libtomcrypt/makefile.mingw	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/makefile.mingw	Fri Jun 26 21:07:34 2020 +0800
@@ -27,7 +27,7 @@
 #Compilation flags
 LTC_CFLAGS  = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS)
 LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS)
-VERSION=1.18.1
+VERSION=1.18.2
 
 #Libraries to be created
 LIBMAIN_S =libtomcrypt.a
--- a/libtomcrypt/makefile.msvc	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/makefile.msvc	Fri Jun 26 21:07:34 2020 +0800
@@ -22,7 +22,7 @@
 #Compilation flags
 LTC_CFLAGS  = /nologo /Isrc/headers/ /Itests/ /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE /DLTC_SOURCE /W3 $(CFLAGS)
 LTC_LDFLAGS = advapi32.lib $(EXTRALIBS)
-VERSION=1.18.1
+VERSION=1.18.2
 
 #Libraries to be created (this makefile builds only static libraries)
 LIBMAIN_S =tomcrypt.lib
--- a/libtomcrypt/makefile.shared	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/makefile.shared	Fri Jun 26 21:07:34 2020 +0800
@@ -16,19 +16,19 @@
 
 PLATFORM := $(shell uname | sed -e 's/_.*//')
 
-ifndef LT
+ifndef LIBTOOL
   ifeq ($(PLATFORM), Darwin)
-    LT:=glibtool
+    LIBTOOL:=glibtool
   else
-    LT:=libtool
+    LIBTOOL:=libtool
   endif
 endif
 ifeq ($(PLATFORM), CYGWIN)
   NO_UNDEFINED:=-no-undefined
 endif
-LTCOMPILE = $(LT) --mode=compile --tag=CC $(CC)
-INSTALL_CMD = $(LT) --mode=install install
-UNINSTALL_CMD = $(LT) --mode=uninstall rm
+LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC)
+INSTALL_CMD = $(LIBTOOL) --mode=install install
+UNINSTALL_CMD = $(LIBTOOL) --mode=uninstall rm
 
 #Output filenames for various targets.
 ifndef LIBNAME
@@ -49,15 +49,15 @@
 LOBJECTS = $(OBJECTS:.o=.lo)
 
 $(LIBNAME): $(OBJECTS)
-	$(LT) --mode=link --tag=CC $(CC) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) $(LOBJECTS) $(EXTRALIBS) -o $@ -rpath $(LIBPATH) -version-info $(VERSION_LT) $(NO_UNDEFINED)
+	$(LIBTOOL) --mode=link --tag=CC $(CC) $(LTC_LDFLAGS) $(LOBJECTS) $(EXTRALIBS) -o $@ -rpath $(LIBPATH) -version-info $(VERSION_LT) $(NO_UNDEFINED)
 
 test: $(call print-help,test,Builds the library and the 'test' application to run all self-tests) $(LIBNAME) $(TOBJECTS)
-	$(LT) --mode=link --tag=CC $(CC) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -o $(TEST) $(TOBJECTS) $(LIBNAME) $(EXTRALIBS)
+	$(LIBTOOL) --mode=link --tag=CC $(CC) $(LTC_LDFLAGS) -o $(TEST) $(TOBJECTS) $(LIBNAME) $(EXTRALIBS)
 
 # build the demos from a template
 define DEMO_template
 $(1): $(call print-help,$(1),Builds the library and the '$(1)' demo) demos/$(1).o $$(LIBNAME)
-	$$(LT) --mode=link --tag=CC $$(CC) $$(LTC_CFLAGS) $$(CPPFLAGS) $$(LTC_LDFLAGS) $$^ $$(EXTRALIBS) -o $(1)
+	$$(LIBTOOL) --mode=link --tag=CC $$(CC) $$(LTC_LDFLAGS) $$^ $$(EXTRALIBS) -o $(1)
 endef
 
 $(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo))))
--- a/libtomcrypt/makefile.unix	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/makefile.unix	Fri Jun 26 21:07:34 2020 +0800
@@ -39,7 +39,7 @@
 #Compilation flags
 LTC_CFLAGS  = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS)
 LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS)
-VERSION=1.18.1
+VERSION=1.18.2
 
 #Libraries to be created (this makefile builds only static libraries)
 LIBMAIN_S =libtomcrypt.a
--- a/libtomcrypt/makefile_include.mk	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/makefile_include.mk	Fri Jun 26 21:07:34 2020 +0800
@@ -3,8 +3,8 @@
 #  (GNU make only)
 
 # The version - BEWARE: VERSION, VERSION_PC and VERSION_LT are updated via ./updatemakes.sh
-VERSION=1.18.1
-VERSION_PC=1.18.1
+VERSION=1.18.2
+VERSION_PC=1.18.2
 # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
 VERSION_LT=1:1
 
@@ -13,9 +13,23 @@
   CROSS_COMPILE:=
 endif
 
-ifeq ($(CC),cc)
+# We only need to go through this dance of determining the right compiler if we're using
+# cross compilation, otherwise $(CC) is fine as-is.
+ifneq (,$(CROSS_COMPILE))
+ifeq ($(origin CC),default)
+CSTR := "\#ifdef __clang__\nCLANG\n\#endif\n"
+ifeq ($(PLATFORM),FreeBSD)
+  # XXX: FreeBSD needs extra escaping for some reason
+  CSTR := $$$(CSTR)
+endif
+ifneq (,$(shell echo $(CSTR) | $(CC) -E - | grep CLANG))
+  CC := $(CROSS_COMPILE)clang
+else
   CC := $(CROSS_COMPILE)gcc
-endif
+endif # Clang
+endif # cc is Make's default
+endif # CROSS_COMPILE non-empty
+
 LD:=$(CROSS_COMPILE)ld
 AR:=$(CROSS_COMPILE)ar
 
@@ -24,7 +38,12 @@
 ARFLAGS:=r
 
 ifndef MAKE
-  MAKE:=make
+# BSDs refer to GNU Make as gmake
+ifneq (,$(findstring $(PLATFORM),FreeBSD OpenBSD DragonFly NetBSD))
+  MAKE=gmake
+else
+  MAKE=make
+endif
 endif
 
 ifndef INSTALL_CMD
@@ -389,7 +408,7 @@
 	$(MAKE) -C doc/ crypt.pdf V=$(V)
 
 
-install_all: $(call print-help,install_all,Install everything - library bins docs tests) install install_bins install_docs install_test
+install_all: $(call print-help,install_all,Install everything - library bins docs tests) install install_bins install_docs
 
 INSTALL_OPTS ?= -m 644
 
--- a/libtomcrypt/notes/cipher_tv.txt	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/notes/cipher_tv.txt	Fri Jun 26 21:07:34 2020 +0800
@@ -1434,6 +1434,58 @@
 
 
 Cipher: 3des
+Key Size: 16 bytes
+ 0: DF0B6C9C31CD0CE4
+ 1: 9B3503FDF249920B
+ 2: 653924639C39E7FF
+ 3: 6A29E0A7F42025BB
+ 4: 1628B719BC875D20
+ 5: 7D77004A18D0C0B2
+ 6: 4D21684EFE962DC1
+ 7: B6BD7F82B648A364
+ 8: 1F87ABAD83D19E96
+ 9: 3DF3533220C3CDED
+10: D0E7D0ABFBA68747
+11: 109FE5B38D74E6C9
+12: AE12C4B4D523784F
+13: 953CD7F264166764
+14: 70B3A87D72FA0A22
+15: 9C9D09AC66AB8F6D
+16: 4A15AEACB35B76F0
+17: EFA32F95623BCF1A
+18: 679901F7737E195C
+19: 221BB06209DDFCF4
+20: 0889A953C60BB1BF
+21: 88F2249380E2D5D9
+22: 5AB26168B7FA24D5
+23: 934229150997D390
+24: 535E4F4C4DA97062
+25: 03E8D711AC2B8154
+26: CB5EF6E72EA3EC49
+27: 9278A864F488C94A
+28: CB91B77401DAF004
+29: 4D0BA1C9794E0099
+30: 9CFA24A21F48043F
+31: BB6B3A33AEEC01F4
+32: F2A8566E0FF6033D
+33: E6AC213000E955E6
+34: 91F5FF42BBE0B81B
+35: 6506D72ADEA70E12
+36: F9BD8C0506C7CC4E
+37: 89CD85D1C98439ED
+38: 409410E3E7D66B10
+39: 4CA64F96F4F3D216
+40: 383D18FBF8C006BC
+41: 3806A8CB006EC243
+42: EE73C06D903D2FCF
+43: 624BFD3FAD7ED9EB
+44: 1B5457F2731FB5D1
+45: 4EC4632DFAC9D5D6
+46: 8F0B3100FAD612C5
+47: F955FCAD55AC6C90
+48: BEB5F023BD413960
+49: BDC369F3288ED754
+
 Key Size: 24 bytes
  0: 58ED248F77F6B19E
  1: DA5C39983FD34F30
--- a/libtomcrypt/src/ciphers/aes/aes.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/ciphers/aes/aes.c	Fri Jun 26 21:07:34 2020 +0800
@@ -10,8 +10,8 @@
 /* AES implementation by Tom St Denis
  *
  * Derived from the Public Domain source code by
- 
----  
+
+---
   * rijndael-alg-fst.c
   *
   * @version 3.0 (December 2000)
@@ -26,13 +26,13 @@
 /**
   @file aes.c
   Implementation of AES
-*/   
+*/
 
 #include "tomcrypt.h"
 
 #ifdef LTC_RIJNDAEL
 
-#ifndef ENCRYPT_ONLY 
+#ifndef ENCRYPT_ONLY
 
 #define SETUP    rijndael_setup
 #define ECB_ENC  rijndael_ecb_encrypt
@@ -125,20 +125,20 @@
     ulong32 temp, *rk;
 #ifndef ENCRYPT_ONLY
     ulong32 *rrk;
-#endif    
+#endif
     LTC_ARGCHK(key  != NULL);
     LTC_ARGCHK(skey != NULL);
-  
+
     if (keylen != 16 && keylen != 24 && keylen != 32) {
        return CRYPT_INVALID_KEYSIZE;
     }
-    
+
     if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
        return CRYPT_INVALID_ROUNDS;
     }
-    
+
     skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
-        
+
     /* setup the forward key */
     i                 = 0;
     rk                = skey->rijndael.eK;
@@ -163,7 +163,7 @@
         LOAD32H(rk[5], key + 20);
         for (;;) {
         #ifdef _MSC_VER
-            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; 
+            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
         #else
             temp = rk[5];
         #endif
@@ -185,7 +185,7 @@
         LOAD32H(rk[7], key + 28);
         for (;;) {
         #ifdef _MSC_VER
-            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; 
+            temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
         #else
             temp = rk[7];
         #endif
@@ -209,11 +209,11 @@
        return CRYPT_ERROR;
     }
 
-#ifndef ENCRYPT_ONLY    
+#ifndef ENCRYPT_ONLY
     /* setup the inverse key now */
     rk   = skey->rijndael.dK;
     rrk  = skey->rijndael.eK + (28 + keylen) - 4;
-    
+
     /* apply the inverse MixColumn transform to all round keys but the first and the last: */
     /* copy first */
     *rk++ = *rrk++;
@@ -221,11 +221,11 @@
     *rk++ = *rrk++;
     *rk   = *rrk;
     rk -= 3; rrk -= 3;
-    
+
     for (i = 1; i < skey->rijndael.Nr; i++) {
         rrk -= 4;
         rk  += 4;
-    #ifdef LTC_SMALL_CODE        
+    #ifdef LTC_SMALL_CODE
         temp = rrk[0];
         rk[0] = setup_mix2(temp);
         temp = rrk[1];
@@ -259,8 +259,8 @@
             Tks1[byte(temp, 2)] ^
             Tks2[byte(temp, 1)] ^
             Tks3[byte(temp, 0)];
-      #endif            
-     
+      #endif
+
     }
 
     /* copy last */
@@ -272,7 +272,7 @@
     *rk   = *rrk;
 #endif /* ENCRYPT_ONLY */
 
-    return CRYPT_OK;   
+    return CRYPT_OK;
 }
 
 /**
@@ -283,21 +283,21 @@
   @return CRYPT_OK if successful
 */
 #ifdef LTC_CLEAN_STACK
-static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
+static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 {
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
     int Nr, r;
-   
+
     LTC_ARGCHK(pt != NULL);
     LTC_ARGCHK(ct != NULL);
     LTC_ARGCHK(skey != NULL);
-    
+
     Nr = skey->rijndael.Nr;
     rk = skey->rijndael.eK;
-    
+
     /*
      * map byte array block to cipher state
      * and add initial round key:
@@ -335,7 +335,7 @@
             Te2(byte(s1, 1)) ^
             Te3(byte(s2, 0)) ^
             rk[3];
-        if (r == Nr-2) { 
+        if (r == Nr-2) {
            break;
         }
         s0 = t0; s1 = t1; s2 = t2; s3 = t3;
@@ -436,7 +436,7 @@
         (Te4_3[byte(t3, 3)]) ^
         (Te4_2[byte(t0, 2)]) ^
         (Te4_1[byte(t1, 1)]) ^
-        (Te4_0[byte(t2, 0)]) ^ 
+        (Te4_0[byte(t2, 0)]) ^
         rk[3];
     STORE32H(s3, ct+12);
 
@@ -444,7 +444,7 @@
 }
 
 #ifdef LTC_CLEAN_STACK
-int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
+int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
    int err = _rijndael_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
@@ -452,17 +452,17 @@
 }
 #endif
 
-#ifndef ENCRYPT_ONLY 
+#ifndef ENCRYPT_ONLY
 
 /**
   Decrypts a block of text with AES
   @param ct The input ciphertext (16 bytes)
   @param pt The output plaintext (16 bytes)
-  @param skey The key as scheduled 
+  @param skey The key as scheduled
   @return CRYPT_OK if successful
 */
 #ifdef LTC_CLEAN_STACK
-static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
+static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
@@ -473,7 +473,7 @@
     LTC_ARGCHK(pt != NULL);
     LTC_ARGCHK(ct != NULL);
     LTC_ARGCHK(skey != NULL);
-    
+
     Nr = skey->rijndael.Nr;
     rk = skey->rijndael.dK;
 
@@ -514,13 +514,13 @@
             Td3(byte(s0, 0)) ^
             rk[3];
         if (r == Nr-2) {
-           break; 
+           break;
         }
         s0 = t0; s1 = t1; s2 = t2; s3 = t3;
     }
     rk += 4;
 
-#else       
+#else
 
     /*
      * Nr - 1 full rounds:
@@ -624,7 +624,7 @@
 
 
 #ifdef LTC_CLEAN_STACK
-int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
+int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
    int err = _rijndael_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
@@ -640,51 +640,51 @@
 {
  #ifndef LTC_TEST
     return CRYPT_NOP;
- #else    
+ #else
  int err;
  static const struct {
      int keylen;
      unsigned char key[32], pt[16], ct[16];
  } tests[] = {
     { 16,
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, 
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
-      { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 
+      { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
         0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
-    }, { 
+    }, {
       24,
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
-      { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 
+      { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
         0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
     }, {
       32,
-      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+      { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
-      { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 
+      { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
         0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
     }
  };
- 
- symmetric_key key;
- unsigned char tmp[2][16];
- int i, y;
- 
- for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
+
+  symmetric_key key;
+  unsigned char tmp[2][16];
+  int i, y;
+
+  for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
     zeromem(&key, sizeof(key));
-    if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { 
+    if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
        return err;
     }
-  
+
     rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
     rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
     if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i) ||
@@ -692,20 +692,20 @@
         return CRYPT_FAIL_TESTVECTOR;
     }
 
-      /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
-      for (y = 0; y < 16; y++) tmp[0][y] = 0;
-      for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
-      for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
-      for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
- }       
- return CRYPT_OK;
+    /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
+    for (y = 0; y < 16; y++) tmp[0][y] = 0;
+    for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
+    for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
+    for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
+  }
+  return CRYPT_OK;
  #endif
 }
 
 #endif /* ENCRYPT_ONLY */
 
 
-/** Terminate the context 
+/** Terminate the context
    @param skey    The scheduled key
 */
 void ECB_DONE(symmetric_key *skey)
--- a/libtomcrypt/src/ciphers/aes/aes_tab.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/ciphers/aes/aes_tab.c	Fri Jun 26 21:07:34 2020 +0800
@@ -94,7 +94,7 @@
     0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL,
 };
 
-#ifndef PELI_TAB
+#if !defined(PELI_TAB) && defined(LTC_SMALL_CODE)
 static const ulong32 Te4[256] = {
     0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL,
     0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL,
@@ -1017,11 +1017,13 @@
 
 #endif /* SMALL CODE */
 
+#ifndef PELI_TAB
 static const ulong32 rcon[] = {
     0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
     0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
     0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
 };
+#endif
 
 #endif /* __LTC_AES_TAB_C__ */
 
--- a/libtomcrypt/src/ciphers/des.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/ciphers/des.c	Fri Jun 26 21:07:34 2020 +0800
@@ -8,14 +8,14 @@
  */
 #include "tomcrypt.h"
 
-/** 
+/**
   @file des.c
   DES code submitted by Dobes Vandermeer
 */
 
 #ifdef LTC_DES
 
-#define EN0 0 
+#define EN0 0
 #define DE1 1
 
 #if 0
@@ -38,7 +38,7 @@
 {
     "3des",
     14,
-    24, 24, 8, 16,
+    16, 24, 8, 16,
     &des3_setup,
     &des3_ecb_encrypt,
     &des3_ecb_decrypt,
@@ -50,7 +50,7 @@
 
 static const ulong32 bytebit[8] =
 {
-    0200, 0100, 040, 020, 010, 04, 02, 01 
+    0200, 0100, 040, 020, 010, 04, 02, 01
 };
 
 static const ulong32 bigbyte[24] =
@@ -60,22 +60,22 @@
     0x8000UL,    0x4000UL,    0x2000UL,    0x1000UL,
     0x800UL,     0x400UL,     0x200UL,     0x100UL,
     0x80UL,      0x40UL,      0x20UL,      0x10UL,
-    0x8UL,       0x4UL,       0x2UL,       0x1L 
+    0x8UL,       0x4UL,       0x2UL,       0x1L
 };
 
 /* Use the key schedule specific in the standard (ANSI X3.92-1981) */
 
 static const unsigned char pc1[56] = {
-    56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,  
-     9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35, 
+    56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,
+     9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35,
     62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
-    13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3 
+    13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3
 };
 
 static const unsigned char totrot[16] = {
     1,   2,  4,  6,
-    8,  10, 12, 14, 
-    15, 17, 19, 21, 
+    8,  10, 12, 14,
+    15, 17, 19, 21,
     23, 25, 27, 28
 };
 
@@ -251,1050 +251,1050 @@
 
 static const ulong64 des_ip[8][256] = {
 
-{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010), 
-  CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010), 
-  CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010), 
-  CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010), 
-  CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010), 
-  CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010), 
-  CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010), 
-  CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010), 
-  CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010), 
-  CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010), 
-  CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010), 
-  CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010), 
-  CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010), 
-  CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010), 
-  CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010), 
-  CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010), 
-  CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010), 
-  CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010), 
-  CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010), 
-  CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010), 
-  CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010), 
-  CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010), 
-  CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010), 
-  CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010), 
-  CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010), 
-  CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010), 
-  CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010), 
-  CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010), 
-  CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010), 
-  CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010), 
-  CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010), 
-  CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010), 
-  CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010), 
-  CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010), 
-  CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010), 
-  CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010), 
-  CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010), 
-  CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010), 
-  CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010), 
-  CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010), 
-  CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010), 
-  CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010), 
-  CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010), 
-  CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010), 
-  CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010), 
-  CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010), 
-  CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010), 
-  CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010), 
-  CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010), 
-  CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010), 
-  CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010), 
-  CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010), 
-  CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010), 
-  CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010), 
-  CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010), 
-  CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010), 
-  CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010), 
-  CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010), 
-  CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010), 
-  CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010), 
-  CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010), 
-  CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010), 
-  CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010), 
+{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010),
+  CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010),
+  CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010),
+  CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010),
+  CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010),
+  CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010),
+  CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010),
+  CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010),
+  CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010),
+  CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010),
+  CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010),
+  CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010),
+  CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010),
+  CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010),
+  CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010),
+  CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010),
+  CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010),
+  CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010),
+  CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010),
+  CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010),
+  CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010),
+  CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010),
+  CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010),
+  CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010),
+  CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010),
+  CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010),
+  CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010),
+  CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010),
+  CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010),
+  CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010),
+  CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010),
+  CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010),
+  CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010),
+  CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010),
+  CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010),
+  CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010),
+  CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010),
+  CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010),
+  CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010),
+  CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010),
+  CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010),
+  CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010),
+  CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010),
+  CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010),
+  CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010),
+  CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010),
+  CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010),
+  CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010),
+  CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010),
+  CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010),
+  CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010),
+  CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010),
+  CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010),
+  CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010),
+  CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010),
+  CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010),
+  CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010),
+  CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010),
+  CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010),
+  CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010),
+  CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010),
+  CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010),
+  CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010),
   CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008), 
-  CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008), 
-  CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808), 
-  CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808), 
-  CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008), 
-  CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008), 
-  CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808), 
-  CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808), 
-  CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008), 
-  CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008), 
-  CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808), 
-  CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808), 
-  CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008), 
-  CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008), 
-  CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808), 
-  CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808), 
-  CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008), 
-  CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008), 
-  CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808), 
-  CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808), 
-  CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008), 
-  CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008), 
-  CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808), 
-  CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808), 
-  CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008), 
-  CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008), 
-  CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808), 
-  CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808), 
-  CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008), 
-  CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008), 
-  CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808), 
-  CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808), 
-  CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008), 
-  CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008), 
-  CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808), 
-  CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808), 
-  CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008), 
-  CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008), 
-  CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808), 
-  CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808), 
-  CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008), 
-  CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008), 
-  CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808), 
-  CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808), 
-  CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008), 
-  CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008), 
-  CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808), 
-  CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808), 
-  CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008), 
-  CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008), 
-  CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808), 
-  CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808), 
-  CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008), 
-  CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008), 
-  CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808), 
-  CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808), 
-  CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008), 
-  CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008), 
-  CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808), 
-  CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808), 
-  CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008), 
-  CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008), 
-  CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008),
+  CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008),
+  CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808),
+  CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808),
+  CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008),
+  CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008),
+  CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808),
+  CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808),
+  CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008),
+  CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008),
+  CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808),
+  CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808),
+  CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008),
+  CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008),
+  CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808),
+  CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808),
+  CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008),
+  CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008),
+  CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808),
+  CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808),
+  CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008),
+  CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008),
+  CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808),
+  CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808),
+  CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008),
+  CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008),
+  CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808),
+  CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808),
+  CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008),
+  CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008),
+  CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808),
+  CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808),
+  CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008),
+  CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008),
+  CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808),
+  CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808),
+  CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008),
+  CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008),
+  CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808),
+  CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808),
+  CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008),
+  CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008),
+  CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808),
+  CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808),
+  CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008),
+  CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008),
+  CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808),
+  CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808),
+  CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008),
+  CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008),
+  CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808),
+  CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808),
+  CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008),
+  CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008),
+  CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808),
+  CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808),
+  CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008),
+  CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008),
+  CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808),
+  CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808),
+  CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008),
+  CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008),
+  CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808),
   CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004), 
-  CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004), 
-  CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404), 
-  CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404), 
-  CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004), 
-  CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004), 
-  CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404), 
-  CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404), 
-  CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004), 
-  CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004), 
-  CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404), 
-  CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404), 
-  CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004), 
-  CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004), 
-  CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404), 
-  CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404), 
-  CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004), 
-  CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004), 
-  CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404), 
-  CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404), 
-  CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004), 
-  CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004), 
-  CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404), 
-  CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404), 
-  CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004), 
-  CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004), 
-  CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404), 
-  CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404), 
-  CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004), 
-  CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004), 
-  CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404), 
-  CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404), 
-  CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004), 
-  CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004), 
-  CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404), 
-  CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404), 
-  CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004), 
-  CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004), 
-  CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404), 
-  CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404), 
-  CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004), 
-  CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004), 
-  CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404), 
-  CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404), 
-  CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004), 
-  CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004), 
-  CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404), 
-  CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404), 
-  CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004), 
-  CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004), 
-  CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404), 
-  CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404), 
-  CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004), 
-  CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004), 
-  CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404), 
-  CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404), 
-  CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004), 
-  CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004), 
-  CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404), 
-  CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404), 
-  CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004), 
-  CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004), 
-  CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004),
+  CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004),
+  CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404),
+  CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404),
+  CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004),
+  CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004),
+  CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404),
+  CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404),
+  CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004),
+  CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004),
+  CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404),
+  CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404),
+  CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004),
+  CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004),
+  CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404),
+  CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404),
+  CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004),
+  CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004),
+  CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404),
+  CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404),
+  CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004),
+  CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004),
+  CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404),
+  CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404),
+  CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004),
+  CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004),
+  CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404),
+  CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404),
+  CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004),
+  CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004),
+  CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404),
+  CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404),
+  CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004),
+  CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004),
+  CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404),
+  CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404),
+  CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004),
+  CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004),
+  CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404),
+  CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404),
+  CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004),
+  CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004),
+  CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404),
+  CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404),
+  CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004),
+  CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004),
+  CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404),
+  CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404),
+  CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004),
+  CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004),
+  CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404),
+  CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404),
+  CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004),
+  CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004),
+  CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404),
+  CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404),
+  CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004),
+  CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004),
+  CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404),
+  CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404),
+  CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004),
+  CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004),
+  CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404),
   CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002), 
-  CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002), 
-  CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202), 
-  CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202), 
-  CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002), 
-  CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002), 
-  CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202), 
-  CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202), 
-  CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002), 
-  CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002), 
-  CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202), 
-  CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202), 
-  CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002), 
-  CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002), 
-  CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202), 
-  CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202), 
-  CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002), 
-  CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002), 
-  CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202), 
-  CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202), 
-  CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002), 
-  CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002), 
-  CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202), 
-  CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202), 
-  CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002), 
-  CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002), 
-  CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202), 
-  CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202), 
-  CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002), 
-  CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002), 
-  CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202), 
-  CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202), 
-  CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002), 
-  CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002), 
-  CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202), 
-  CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202), 
-  CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002), 
-  CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002), 
-  CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202), 
-  CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202), 
-  CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002), 
-  CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002), 
-  CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202), 
-  CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202), 
-  CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002), 
-  CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002), 
-  CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202), 
-  CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202), 
-  CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002), 
-  CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002), 
-  CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202), 
-  CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202), 
-  CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002), 
-  CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002), 
-  CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202), 
-  CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202), 
-  CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002), 
-  CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002), 
-  CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202), 
-  CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202), 
-  CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002), 
-  CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002), 
-  CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002),
+  CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002),
+  CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202),
+  CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202),
+  CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002),
+  CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002),
+  CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202),
+  CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202),
+  CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002),
+  CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002),
+  CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202),
+  CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202),
+  CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002),
+  CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002),
+  CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202),
+  CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202),
+  CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002),
+  CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002),
+  CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202),
+  CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202),
+  CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002),
+  CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002),
+  CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202),
+  CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202),
+  CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002),
+  CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002),
+  CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202),
+  CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202),
+  CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002),
+  CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002),
+  CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202),
+  CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202),
+  CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002),
+  CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002),
+  CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202),
+  CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202),
+  CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002),
+  CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002),
+  CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202),
+  CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202),
+  CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002),
+  CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002),
+  CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202),
+  CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202),
+  CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002),
+  CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002),
+  CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202),
+  CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202),
+  CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002),
+  CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002),
+  CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202),
+  CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202),
+  CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002),
+  CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002),
+  CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202),
+  CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202),
+  CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002),
+  CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002),
+  CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202),
+  CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202),
+  CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002),
+  CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002),
+  CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202),
   CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100), 
-  CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100), 
-  CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100), 
-  CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100), 
-  CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100), 
-  CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100), 
-  CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100), 
-  CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100), 
-  CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100), 
-  CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100), 
-  CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100), 
-  CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100), 
-  CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100), 
-  CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100), 
-  CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100), 
-  CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100), 
-  CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100), 
-  CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100), 
-  CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100), 
-  CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100), 
-  CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100), 
-  CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100), 
-  CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100), 
-  CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100), 
-  CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100), 
-  CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100), 
-  CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100), 
-  CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100), 
-  CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100), 
-  CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100), 
-  CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100), 
-  CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100), 
-  CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101), 
-  CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101), 
-  CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101), 
-  CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101), 
-  CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101), 
-  CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101), 
-  CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101), 
-  CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101), 
-  CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101), 
-  CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101), 
-  CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101), 
-  CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101), 
-  CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101), 
-  CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101), 
-  CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101), 
-  CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101), 
-  CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101), 
-  CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101), 
-  CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101), 
-  CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101), 
-  CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101), 
-  CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101), 
-  CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101), 
-  CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101), 
-  CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101), 
-  CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101), 
-  CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101), 
-  CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101), 
-  CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101), 
-  CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101), 
-  CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100),
+  CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100),
+  CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100),
+  CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100),
+  CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100),
+  CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100),
+  CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100),
+  CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100),
+  CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100),
+  CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100),
+  CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100),
+  CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100),
+  CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100),
+  CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100),
+  CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100),
+  CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100),
+  CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100),
+  CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100),
+  CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100),
+  CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100),
+  CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100),
+  CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100),
+  CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100),
+  CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100),
+  CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100),
+  CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100),
+  CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100),
+  CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100),
+  CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100),
+  CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100),
+  CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100),
+  CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100),
+  CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101),
+  CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101),
+  CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101),
+  CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101),
+  CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101),
+  CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101),
+  CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101),
+  CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101),
+  CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101),
+  CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101),
+  CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101),
+  CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101),
+  CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101),
+  CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101),
+  CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101),
+  CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101),
+  CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101),
+  CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101),
+  CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101),
+  CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101),
+  CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101),
+  CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101),
+  CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101),
+  CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101),
+  CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101),
+  CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101),
+  CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101),
+  CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101),
+  CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101),
+  CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101),
+  CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101),
   CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080), 
-  CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080), 
-  CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080), 
-  CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080), 
-  CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080), 
-  CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080), 
-  CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080), 
-  CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080), 
-  CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080), 
-  CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080), 
-  CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080), 
-  CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080), 
-  CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080), 
-  CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080), 
-  CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080), 
-  CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080), 
-  CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080), 
-  CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080), 
-  CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080), 
-  CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080), 
-  CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080), 
-  CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080), 
-  CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080), 
-  CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080), 
-  CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080), 
-  CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080), 
-  CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080), 
-  CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080), 
-  CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080), 
-  CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080), 
-  CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080), 
-  CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080), 
-  CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080), 
-  CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080), 
-  CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080), 
-  CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080), 
-  CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080), 
-  CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080), 
-  CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080), 
-  CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080), 
-  CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080), 
-  CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080), 
-  CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080), 
-  CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080), 
-  CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080), 
-  CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080), 
-  CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080), 
-  CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080), 
-  CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080), 
-  CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080), 
-  CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080), 
-  CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080), 
-  CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080), 
-  CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080), 
-  CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080), 
-  CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080), 
-  CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080), 
-  CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080), 
-  CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080), 
-  CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080), 
-  CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080), 
-  CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080), 
-  CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080),
+  CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080),
+  CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080),
+  CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080),
+  CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080),
+  CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080),
+  CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080),
+  CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080),
+  CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080),
+  CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080),
+  CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080),
+  CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080),
+  CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080),
+  CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080),
+  CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080),
+  CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080),
+  CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080),
+  CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080),
+  CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080),
+  CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080),
+  CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080),
+  CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080),
+  CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080),
+  CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080),
+  CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080),
+  CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080),
+  CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080),
+  CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080),
+  CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080),
+  CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080),
+  CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080),
+  CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080),
+  CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080),
+  CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080),
+  CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080),
+  CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080),
+  CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080),
+  CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080),
+  CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080),
+  CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080),
+  CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080),
+  CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080),
+  CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080),
+  CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080),
+  CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080),
+  CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080),
+  CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080),
+  CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080),
+  CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080),
+  CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080),
+  CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080),
+  CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080),
+  CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080),
+  CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080),
+  CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080),
+  CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080),
+  CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080),
+  CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080),
+  CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080),
+  CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080),
+  CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080),
+  CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080),
+  CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080),
   CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040), 
-  CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040), 
-  CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040), 
-  CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040), 
-  CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040), 
-  CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040), 
-  CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040), 
-  CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040), 
-  CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040), 
-  CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040), 
-  CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040), 
-  CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040), 
-  CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040), 
-  CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040), 
-  CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040), 
-  CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040), 
-  CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040), 
-  CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040), 
-  CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040), 
-  CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040), 
-  CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040), 
-  CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040), 
-  CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040), 
-  CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040), 
-  CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040), 
-  CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040), 
-  CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040), 
-  CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040), 
-  CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040), 
-  CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040), 
-  CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040), 
-  CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040), 
-  CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040), 
-  CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040), 
-  CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040), 
-  CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040), 
-  CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040), 
-  CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040), 
-  CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040), 
-  CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040), 
-  CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040), 
-  CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040), 
-  CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040), 
-  CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040), 
-  CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040), 
-  CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040), 
-  CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040), 
-  CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040), 
-  CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040), 
-  CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040), 
-  CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040), 
-  CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040), 
-  CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040), 
-  CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040), 
-  CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040), 
-  CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040), 
-  CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040), 
-  CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040), 
-  CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040), 
-  CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040), 
-  CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040), 
-  CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040), 
-  CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040),
+  CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040),
+  CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040),
+  CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040),
+  CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040),
+  CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040),
+  CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040),
+  CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040),
+  CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040),
+  CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040),
+  CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040),
+  CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040),
+  CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040),
+  CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040),
+  CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040),
+  CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040),
+  CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040),
+  CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040),
+  CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040),
+  CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040),
+  CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040),
+  CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040),
+  CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040),
+  CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040),
+  CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040),
+  CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040),
+  CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040),
+  CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040),
+  CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040),
+  CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040),
+  CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040),
+  CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040),
+  CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040),
+  CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040),
+  CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040),
+  CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040),
+  CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040),
+  CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040),
+  CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040),
+  CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040),
+  CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040),
+  CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040),
+  CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040),
+  CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040),
+  CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040),
+  CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040),
+  CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040),
+  CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040),
+  CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040),
+  CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040),
+  CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040),
+  CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040),
+  CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040),
+  CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040),
+  CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040),
+  CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040),
+  CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040),
+  CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040),
+  CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040),
+  CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040),
+  CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040),
+  CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040),
+  CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040),
   CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020), 
-  CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020), 
-  CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020), 
-  CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020), 
-  CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020), 
-  CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020), 
-  CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020), 
-  CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020), 
-  CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020), 
-  CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020), 
-  CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020), 
-  CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020), 
-  CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020), 
-  CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020), 
-  CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020), 
-  CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020), 
-  CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020), 
-  CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020), 
-  CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020), 
-  CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020), 
-  CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020), 
-  CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020), 
-  CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020), 
-  CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020), 
-  CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020), 
-  CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020), 
-  CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020), 
-  CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020), 
-  CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020), 
-  CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020), 
-  CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020), 
-  CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020), 
-  CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020), 
-  CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020), 
-  CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020), 
-  CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020), 
-  CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020), 
-  CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020), 
-  CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020), 
-  CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020), 
-  CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020), 
-  CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020), 
-  CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020), 
-  CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020), 
-  CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020), 
-  CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020), 
-  CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020), 
-  CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020), 
-  CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020), 
-  CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020), 
-  CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020), 
-  CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020), 
-  CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020), 
-  CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020), 
-  CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020), 
-  CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020), 
-  CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020), 
-  CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020), 
-  CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020), 
-  CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020), 
-  CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020), 
-  CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020), 
-  CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020),
+  CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020),
+  CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020),
+  CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020),
+  CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020),
+  CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020),
+  CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020),
+  CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020),
+  CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020),
+  CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020),
+  CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020),
+  CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020),
+  CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020),
+  CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020),
+  CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020),
+  CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020),
+  CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020),
+  CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020),
+  CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020),
+  CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020),
+  CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020),
+  CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020),
+  CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020),
+  CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020),
+  CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020),
+  CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020),
+  CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020),
+  CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020),
+  CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020),
+  CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020),
+  CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020),
+  CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020),
+  CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020),
+  CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020),
+  CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020),
+  CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020),
+  CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020),
+  CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020),
+  CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020),
+  CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020),
+  CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020),
+  CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020),
+  CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020),
+  CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020),
+  CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020),
+  CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020),
+  CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020),
+  CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020),
+  CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020),
+  CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020),
+  CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020),
+  CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020),
+  CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020),
+  CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020),
+  CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020),
+  CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020),
+  CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020),
+  CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020),
+  CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020),
+  CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020),
+  CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020),
+  CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020),
+  CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020),
   CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020)
   }};
-  
+
 static const ulong64 des_fp[8][256] = {
 
-{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000), 
-  CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000), 
-  CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200), 
-  CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200), 
-  CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002), 
-  CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002), 
-  CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202), 
-  CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202), 
-  CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000), 
-  CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000), 
-  CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200), 
-  CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200), 
-  CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002), 
-  CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002), 
-  CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202), 
-  CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202), 
-  CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000), 
-  CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000), 
-  CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200), 
-  CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200), 
-  CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002), 
-  CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002), 
-  CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202), 
-  CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202), 
-  CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000), 
-  CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000), 
-  CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200), 
-  CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200), 
-  CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002), 
-  CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002), 
-  CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202), 
-  CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202), 
-  CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000), 
-  CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000), 
-  CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200), 
-  CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200), 
-  CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002), 
-  CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002), 
-  CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202), 
-  CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202), 
-  CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000), 
-  CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000), 
-  CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200), 
-  CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200), 
-  CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002), 
-  CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002), 
-  CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202), 
-  CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202), 
-  CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000), 
-  CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000), 
-  CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200), 
-  CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200), 
-  CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002), 
-  CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002), 
-  CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202), 
-  CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202), 
-  CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000), 
-  CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000), 
-  CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200), 
-  CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200), 
-  CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002), 
-  CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002), 
-  CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202), 
+{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000),
+  CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000),
+  CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200),
+  CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200),
+  CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002),
+  CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002),
+  CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202),
+  CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202),
+  CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000),
+  CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000),
+  CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200),
+  CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200),
+  CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002),
+  CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002),
+  CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202),
+  CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202),
+  CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000),
+  CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000),
+  CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200),
+  CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200),
+  CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002),
+  CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002),
+  CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202),
+  CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202),
+  CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000),
+  CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000),
+  CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200),
+  CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200),
+  CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002),
+  CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002),
+  CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202),
+  CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202),
+  CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000),
+  CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000),
+  CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200),
+  CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200),
+  CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002),
+  CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002),
+  CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202),
+  CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202),
+  CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000),
+  CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000),
+  CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200),
+  CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200),
+  CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002),
+  CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002),
+  CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202),
+  CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202),
+  CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000),
+  CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000),
+  CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200),
+  CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200),
+  CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002),
+  CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002),
+  CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202),
+  CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202),
+  CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000),
+  CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000),
+  CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200),
+  CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200),
+  CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002),
+  CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002),
+  CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202),
   CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000), 
-  CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000), 
-  CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800), 
-  CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800), 
-  CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008), 
-  CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008), 
-  CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808), 
-  CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808), 
-  CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000), 
-  CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000), 
-  CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800), 
-  CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800), 
-  CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008), 
-  CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008), 
-  CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808), 
-  CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808), 
-  CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000), 
-  CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000), 
-  CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800), 
-  CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800), 
-  CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008), 
-  CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008), 
-  CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808), 
-  CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808), 
-  CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000), 
-  CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000), 
-  CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800), 
-  CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800), 
-  CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008), 
-  CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008), 
-  CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808), 
-  CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808), 
-  CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000), 
-  CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000), 
-  CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800), 
-  CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800), 
-  CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008), 
-  CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008), 
-  CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808), 
-  CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808), 
-  CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000), 
-  CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000), 
-  CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800), 
-  CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800), 
-  CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008), 
-  CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008), 
-  CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808), 
-  CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808), 
-  CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000), 
-  CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000), 
-  CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800), 
-  CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800), 
-  CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008), 
-  CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008), 
-  CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808), 
-  CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808), 
-  CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000), 
-  CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000), 
-  CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800), 
-  CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800), 
-  CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008), 
-  CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008), 
-  CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000),
+  CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000),
+  CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800),
+  CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800),
+  CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008),
+  CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008),
+  CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808),
+  CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808),
+  CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000),
+  CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000),
+  CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800),
+  CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800),
+  CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008),
+  CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008),
+  CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808),
+  CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808),
+  CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000),
+  CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000),
+  CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800),
+  CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800),
+  CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008),
+  CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008),
+  CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808),
+  CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808),
+  CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000),
+  CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000),
+  CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800),
+  CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800),
+  CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008),
+  CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008),
+  CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808),
+  CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808),
+  CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000),
+  CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000),
+  CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800),
+  CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800),
+  CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008),
+  CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008),
+  CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808),
+  CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808),
+  CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000),
+  CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000),
+  CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800),
+  CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800),
+  CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008),
+  CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008),
+  CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808),
+  CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808),
+  CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000),
+  CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000),
+  CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800),
+  CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800),
+  CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008),
+  CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008),
+  CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808),
+  CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808),
+  CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000),
+  CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000),
+  CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800),
+  CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800),
+  CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008),
+  CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008),
+  CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808),
   CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000), 
-  CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000), 
-  CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000), 
-  CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000), 
-  CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020), 
-  CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020), 
-  CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020), 
-  CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020), 
-  CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000), 
-  CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000), 
-  CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000), 
-  CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000), 
-  CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020), 
-  CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020), 
-  CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020), 
-  CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020), 
-  CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000), 
-  CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000), 
-  CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000), 
-  CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000), 
-  CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020), 
-  CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020), 
-  CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020), 
-  CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020), 
-  CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000), 
-  CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000), 
-  CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000), 
-  CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000), 
-  CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020), 
-  CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020), 
-  CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020), 
-  CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020), 
-  CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000), 
-  CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000), 
-  CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000), 
-  CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000), 
-  CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020), 
-  CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020), 
-  CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020), 
-  CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020), 
-  CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000), 
-  CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000), 
-  CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000), 
-  CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000), 
-  CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020), 
-  CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020), 
-  CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020), 
-  CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020), 
-  CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000), 
-  CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000), 
-  CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000), 
-  CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000), 
-  CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020), 
-  CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020), 
-  CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020), 
-  CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020), 
-  CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000), 
-  CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000), 
-  CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000), 
-  CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000), 
-  CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020), 
-  CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020), 
-  CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000),
+  CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000),
+  CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000),
+  CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000),
+  CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020),
+  CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020),
+  CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020),
+  CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020),
+  CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000),
+  CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000),
+  CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000),
+  CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000),
+  CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020),
+  CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020),
+  CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020),
+  CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020),
+  CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000),
+  CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000),
+  CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000),
+  CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000),
+  CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020),
+  CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020),
+  CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020),
+  CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020),
+  CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000),
+  CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000),
+  CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000),
+  CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000),
+  CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020),
+  CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020),
+  CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020),
+  CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020),
+  CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000),
+  CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000),
+  CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000),
+  CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000),
+  CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020),
+  CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020),
+  CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020),
+  CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020),
+  CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000),
+  CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000),
+  CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000),
+  CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000),
+  CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020),
+  CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020),
+  CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020),
+  CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020),
+  CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000),
+  CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000),
+  CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000),
+  CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000),
+  CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020),
+  CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020),
+  CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020),
+  CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020),
+  CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000),
+  CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000),
+  CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000),
+  CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000),
+  CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020),
+  CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020),
+  CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020),
   CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000), 
-  CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000), 
-  CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000), 
-  CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000), 
-  CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080), 
-  CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080), 
-  CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080), 
-  CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080), 
-  CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000), 
-  CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000), 
-  CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000), 
-  CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000), 
-  CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080), 
-  CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080), 
-  CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080), 
-  CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080), 
-  CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000), 
-  CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000), 
-  CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000), 
-  CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000), 
-  CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080), 
-  CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080), 
-  CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080), 
-  CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080), 
-  CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000), 
-  CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000), 
-  CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000), 
-  CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000), 
-  CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080), 
-  CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080), 
-  CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080), 
-  CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080), 
-  CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000), 
-  CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000), 
-  CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000), 
-  CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000), 
-  CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080), 
-  CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080), 
-  CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080), 
-  CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080), 
-  CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000), 
-  CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000), 
-  CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000), 
-  CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000), 
-  CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080), 
-  CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080), 
-  CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080), 
-  CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080), 
-  CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000), 
-  CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000), 
-  CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000), 
-  CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000), 
-  CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080), 
-  CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080), 
-  CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080), 
-  CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080), 
-  CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000), 
-  CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000), 
-  CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000), 
-  CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000), 
-  CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080), 
-  CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080), 
-  CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000),
+  CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000),
+  CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000),
+  CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000),
+  CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080),
+  CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080),
+  CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080),
+  CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080),
+  CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000),
+  CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000),
+  CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000),
+  CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000),
+  CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080),
+  CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080),
+  CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080),
+  CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080),
+  CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000),
+  CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000),
+  CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000),
+  CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000),
+  CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080),
+  CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080),
+  CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080),
+  CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080),
+  CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000),
+  CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000),
+  CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000),
+  CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000),
+  CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080),
+  CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080),
+  CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080),
+  CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080),
+  CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000),
+  CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000),
+  CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000),
+  CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000),
+  CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080),
+  CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080),
+  CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080),
+  CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080),
+  CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000),
+  CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000),
+  CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000),
+  CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000),
+  CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080),
+  CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080),
+  CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080),
+  CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080),
+  CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000),
+  CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000),
+  CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000),
+  CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000),
+  CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080),
+  CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080),
+  CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080),
+  CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080),
+  CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000),
+  CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000),
+  CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000),
+  CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000),
+  CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080),
+  CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080),
+  CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080),
   CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000), 
-  CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000), 
-  CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100), 
-  CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100), 
-  CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001), 
-  CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001), 
-  CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101), 
-  CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101), 
-  CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000), 
-  CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000), 
-  CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100), 
-  CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100), 
-  CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001), 
-  CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001), 
-  CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101), 
-  CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101), 
-  CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000), 
-  CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000), 
-  CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100), 
-  CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100), 
-  CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001), 
-  CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001), 
-  CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101), 
-  CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101), 
-  CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000), 
-  CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000), 
-  CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100), 
-  CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100), 
-  CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001), 
-  CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001), 
-  CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101), 
-  CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101), 
-  CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000), 
-  CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000), 
-  CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100), 
-  CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100), 
-  CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001), 
-  CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001), 
-  CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101), 
-  CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101), 
-  CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000), 
-  CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000), 
-  CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100), 
-  CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100), 
-  CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001), 
-  CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001), 
-  CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101), 
-  CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101), 
-  CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000), 
-  CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000), 
-  CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100), 
-  CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100), 
-  CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001), 
-  CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001), 
-  CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101), 
-  CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101), 
-  CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000), 
-  CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000), 
-  CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100), 
-  CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100), 
-  CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001), 
-  CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001), 
-  CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000),
+  CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000),
+  CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100),
+  CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100),
+  CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001),
+  CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001),
+  CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101),
+  CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101),
+  CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000),
+  CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000),
+  CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100),
+  CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100),
+  CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001),
+  CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001),
+  CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101),
+  CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101),
+  CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000),
+  CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000),
+  CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100),
+  CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100),
+  CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001),
+  CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001),
+  CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101),
+  CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101),
+  CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000),
+  CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000),
+  CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100),
+  CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100),
+  CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001),
+  CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001),
+  CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101),
+  CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101),
+  CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000),
+  CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000),
+  CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100),
+  CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100),
+  CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001),
+  CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001),
+  CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101),
+  CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101),
+  CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000),
+  CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000),
+  CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100),
+  CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100),
+  CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001),
+  CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001),
+  CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101),
+  CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101),
+  CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000),
+  CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000),
+  CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100),
+  CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100),
+  CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001),
+  CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001),
+  CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101),
+  CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101),
+  CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000),
+  CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000),
+  CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100),
+  CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100),
+  CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001),
+  CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001),
+  CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101),
   CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000), 
-  CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000), 
-  CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400), 
-  CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400), 
-  CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004), 
-  CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004), 
-  CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404), 
-  CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404), 
-  CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000), 
-  CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000), 
-  CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400), 
-  CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400), 
-  CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004), 
-  CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004), 
-  CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404), 
-  CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404), 
-  CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000), 
-  CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000), 
-  CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400), 
-  CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400), 
-  CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004), 
-  CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004), 
-  CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404), 
-  CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404), 
-  CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000), 
-  CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000), 
-  CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400), 
-  CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400), 
-  CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004), 
-  CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004), 
-  CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404), 
-  CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404), 
-  CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000), 
-  CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000), 
-  CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400), 
-  CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400), 
-  CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004), 
-  CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004), 
-  CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404), 
-  CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404), 
-  CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000), 
-  CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000), 
-  CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400), 
-  CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400), 
-  CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004), 
-  CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004), 
-  CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404), 
-  CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404), 
-  CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000), 
-  CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000), 
-  CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400), 
-  CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400), 
-  CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004), 
-  CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004), 
-  CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404), 
-  CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404), 
-  CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000), 
-  CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000), 
-  CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400), 
-  CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400), 
-  CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004), 
-  CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004), 
-  CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000),
+  CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000),
+  CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400),
+  CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400),
+  CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004),
+  CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004),
+  CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404),
+  CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404),
+  CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000),
+  CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000),
+  CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400),
+  CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400),
+  CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004),
+  CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004),
+  CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404),
+  CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404),
+  CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000),
+  CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000),
+  CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400),
+  CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400),
+  CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004),
+  CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004),
+  CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404),
+  CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404),
+  CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000),
+  CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000),
+  CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400),
+  CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400),
+  CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004),
+  CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004),
+  CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404),
+  CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404),
+  CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000),
+  CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000),
+  CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400),
+  CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400),
+  CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004),
+  CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004),
+  CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404),
+  CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404),
+  CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000),
+  CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000),
+  CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400),
+  CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400),
+  CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004),
+  CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004),
+  CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404),
+  CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404),
+  CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000),
+  CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000),
+  CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400),
+  CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400),
+  CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004),
+  CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004),
+  CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404),
+  CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404),
+  CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000),
+  CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000),
+  CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400),
+  CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400),
+  CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004),
+  CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004),
+  CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404),
   CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000), 
-  CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000), 
-  CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000), 
-  CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000), 
-  CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010), 
-  CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010), 
-  CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010), 
-  CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010), 
-  CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000), 
-  CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000), 
-  CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000), 
-  CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000), 
-  CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010), 
-  CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010), 
-  CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010), 
-  CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010), 
-  CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000), 
-  CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000), 
-  CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000), 
-  CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000), 
-  CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010), 
-  CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010), 
-  CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010), 
-  CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010), 
-  CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000), 
-  CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000), 
-  CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000), 
-  CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000), 
-  CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010), 
-  CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010), 
-  CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010), 
-  CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010), 
-  CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000), 
-  CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000), 
-  CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000), 
-  CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000), 
-  CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010), 
-  CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010), 
-  CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010), 
-  CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010), 
-  CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000), 
-  CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000), 
-  CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000), 
-  CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000), 
-  CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010), 
-  CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010), 
-  CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010), 
-  CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010), 
-  CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000), 
-  CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000), 
-  CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000), 
-  CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000), 
-  CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010), 
-  CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010), 
-  CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010), 
-  CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010), 
-  CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000), 
-  CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000), 
-  CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000), 
-  CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000), 
-  CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010), 
-  CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010), 
-  CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000),
+  CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000),
+  CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000),
+  CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000),
+  CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010),
+  CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010),
+  CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010),
+  CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010),
+  CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000),
+  CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000),
+  CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000),
+  CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000),
+  CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010),
+  CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010),
+  CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010),
+  CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010),
+  CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000),
+  CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000),
+  CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000),
+  CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000),
+  CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010),
+  CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010),
+  CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010),
+  CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010),
+  CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000),
+  CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000),
+  CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000),
+  CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000),
+  CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010),
+  CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010),
+  CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010),
+  CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010),
+  CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000),
+  CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000),
+  CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000),
+  CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000),
+  CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010),
+  CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010),
+  CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010),
+  CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010),
+  CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000),
+  CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000),
+  CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000),
+  CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000),
+  CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010),
+  CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010),
+  CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010),
+  CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010),
+  CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000),
+  CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000),
+  CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000),
+  CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000),
+  CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010),
+  CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010),
+  CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010),
+  CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010),
+  CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000),
+  CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000),
+  CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000),
+  CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000),
+  CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010),
+  CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010),
+  CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010),
   CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010)
-  }, 
-{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000), 
-  CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000), 
-  CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000), 
-  CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000), 
-  CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040), 
-  CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040), 
-  CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040), 
-  CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040), 
-  CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000), 
-  CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000), 
-  CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000), 
-  CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000), 
-  CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040), 
-  CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040), 
-  CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040), 
-  CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040), 
-  CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000), 
-  CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000), 
-  CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000), 
-  CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000), 
-  CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040), 
-  CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040), 
-  CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040), 
-  CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040), 
-  CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000), 
-  CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000), 
-  CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000), 
-  CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000), 
-  CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040), 
-  CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040), 
-  CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040), 
-  CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040), 
-  CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000), 
-  CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000), 
-  CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000), 
-  CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000), 
-  CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040), 
-  CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040), 
-  CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040), 
-  CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040), 
-  CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000), 
-  CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000), 
-  CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000), 
-  CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000), 
-  CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040), 
-  CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040), 
-  CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040), 
-  CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040), 
-  CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000), 
-  CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000), 
-  CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000), 
-  CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000), 
-  CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040), 
-  CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040), 
-  CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040), 
-  CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040), 
-  CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000), 
-  CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000), 
-  CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000), 
-  CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000), 
-  CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040), 
-  CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040), 
-  CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040), 
+  },
+{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000),
+  CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000),
+  CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000),
+  CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000),
+  CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040),
+  CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040),
+  CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040),
+  CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040),
+  CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000),
+  CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000),
+  CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000),
+  CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000),
+  CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040),
+  CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040),
+  CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040),
+  CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040),
+  CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000),
+  CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000),
+  CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000),
+  CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000),
+  CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040),
+  CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040),
+  CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040),
+  CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040),
+  CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000),
+  CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000),
+  CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000),
+  CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000),
+  CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040),
+  CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040),
+  CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040),
+  CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040),
+  CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000),
+  CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000),
+  CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000),
+  CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000),
+  CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040),
+  CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040),
+  CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040),
+  CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040),
+  CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000),
+  CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000),
+  CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000),
+  CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000),
+  CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040),
+  CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040),
+  CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040),
+  CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040),
+  CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000),
+  CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000),
+  CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000),
+  CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000),
+  CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040),
+  CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040),
+  CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040),
+  CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040),
+  CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000),
+  CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000),
+  CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000),
+  CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000),
+  CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040),
+  CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040),
+  CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040),
   CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040)
   }};
-  
+
 #endif
 
 
@@ -1427,11 +1427,11 @@
 
     right = ROLc(right, 1);
     work = (leftt ^ right) & 0xaaaaaaaaL;
-    
+
     leftt ^= work;
     right ^= work;
     leftt = ROLc(leftt, 1);
-#else 
+#else
    {
       ulong64 tmp;
       tmp = des_ip[0][byte(leftt, 0)] ^
@@ -1450,9 +1450,9 @@
     for (cur_round = 0; cur_round < 8; cur_round++) {
         work  = RORc(right, 4) ^ *keys++;
         leftt ^= SP7[work        & 0x3fL]
-              ^ SP5[(work >>  8) & 0x3fL]
-              ^ SP3[(work >> 16) & 0x3fL]
-              ^ SP1[(work >> 24) & 0x3fL];
+              ^  SP5[(work >>  8) & 0x3fL]
+              ^  SP3[(work >> 16) & 0x3fL]
+              ^  SP1[(work >> 24) & 0x3fL];
         work  = right ^ *keys++;
         leftt ^= SP8[ work        & 0x3fL]
               ^  SP6[(work >>  8) & 0x3fL]
@@ -1471,7 +1471,7 @@
               ^  SP2[(work >> 24) & 0x3fL];
     }
 
-#ifdef LTC_SMALL_CODE    
+#ifdef LTC_SMALL_CODE
     right = RORc(right, 1);
     work = (leftt ^ right) & 0xaaaaaaaaL;
     leftt ^= work;
@@ -1490,7 +1490,7 @@
     work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
     leftt ^= work;
     right ^= (work << 4);
-#else 
+#else
    {
       ulong64 tmp;
       tmp = des_fp[0][byte(leftt, 0)] ^
@@ -1505,7 +1505,7 @@
       right = (ulong32)(tmp & 0xFFFFFFFFUL);
    }
 #endif
-    
+
     block[0] = right;
     block[1] = leftt;
 }
@@ -1571,7 +1571,7 @@
     deskey(key,    EN0, skey->des3.ek[0]);
     deskey(key+8,  DE1, skey->des3.ek[1]);
     if (keylen == 24) {
-    deskey(key+16, EN0, skey->des3.ek[2]);
+        deskey(key+16, EN0, skey->des3.ek[2]);
     } else {
         /* two-key 3DES: K3=K1 */
         deskey(key, EN0, skey->des3.ek[2]);
@@ -1580,7 +1580,7 @@
     deskey(key,    DE1, skey->des3.dk[2]);
     deskey(key+8,  EN0, skey->des3.dk[1]);
     if (keylen == 24) {
-    deskey(key+16, DE1, skey->des3.dk[0]);
+        deskey(key+16, DE1, skey->des3.dk[0]);
     } else {
         /* two-key 3DES: K3=K1 */
         deskey(key, DE1, skey->des3.dk[0]);
@@ -1615,7 +1615,7 @@
   Decrypts a block of text with LTC_DES
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
-  @param skey The key as scheduled 
+  @param skey The key as scheduled
   @return CRYPT_OK if successful
 */
 int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
@@ -1628,7 +1628,7 @@
     LOAD32H(work[1], ct+4);
     desfunc(work, skey->des.dk);
     STORE32H(work[0],pt+0);
-    STORE32H(work[1],pt+4);  
+    STORE32H(work[1],pt+4);
     return CRYPT_OK;
 }
 #endif
@@ -1643,7 +1643,7 @@
 int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
     ulong32 work[2];
-    
+
     LTC_ARGCHK(pt   != NULL);
     LTC_ARGCHK(ct   != NULL);
     LTC_ARGCHK(skey != NULL);
@@ -1661,7 +1661,7 @@
   Decrypts a block of text with 3LTC_DES-EDE
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
-  @param skey The key as scheduled 
+  @param skey The key as scheduled
   @return CRYPT_OK if successful
 */
 int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
@@ -1689,7 +1689,7 @@
 {
  #ifndef LTC_TEST
     return CRYPT_NOP;
- #else    
+ #else
     int err;
     static const struct des_test_case {
         int num, mode; /* mode 1 = encrypt */
@@ -1720,7 +1720,7 @@
                     { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F },
                     { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
         { 9, 1,     { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
-                    { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 }, 
+                    { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 },
                     { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
         {10, 1,     { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
                     { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A },
@@ -1752,7 +1752,7 @@
                     { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } },
         { 9, 0,     { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
                     { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-                    { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } }, 
+                    { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } },
         {10, 0,     { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
                     { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
                     { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } },
@@ -1978,7 +1978,7 @@
         if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) {
            return err;
         }
-        if (cases[i].mode != 0) { 
+        if (cases[i].mode != 0) {
            des_ecb_encrypt(cases[i].txt, tmp, &des);
         } else {
            des_ecb_decrypt(cases[i].txt, tmp, &des);
@@ -1988,11 +1988,11 @@
            return CRYPT_FAIL_TESTVECTOR;
         }
 
-      /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
-      for (y = 0; y < 8; y++) tmp[y] = 0;
-      for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des);
-      for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des);
-      for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR;
+        /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
+        for (y = 0; y < 8; y++) tmp[y] = 0;
+        for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des);
+        for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des);
+        for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR;
     }
 
     return CRYPT_OK;
@@ -2004,7 +2004,7 @@
 {
  #ifndef LTC_TEST
     return CRYPT_NOP;
- #else    
+ #else
    unsigned char key[24], pt[8], ct[8], tmp[8];
    symmetric_key skey;
    int x, err;
@@ -2016,7 +2016,7 @@
    for (x = 0; x < 8; x++) {
        pt[x] = x;
    }
-   
+
    for (x = 0; x < 24; x++) {
        key[x] = x;
    }
@@ -2024,20 +2024,20 @@
    if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) {
       return err;
    }
-   
+
    des3_ecb_encrypt(pt, ct, &skey);
    des3_ecb_decrypt(ct, tmp, &skey);
-   
+
    if (compare_testvector(pt, 8, tmp, 8, "3DES", 0) != 0) {
       return CRYPT_FAIL_TESTVECTOR;
    }
-   
+
    return CRYPT_OK;
  #endif
 }
 
 #if 0
-/** Terminate the context 
+/** Terminate the context
    @param skey    The scheduled key
 */
 void des_done(symmetric_key *skey)
@@ -2046,7 +2046,7 @@
 }
 #endif
 
-/** Terminate the context 
+/** Terminate the context
    @param skey    The scheduled key
 */
 void des3_done(symmetric_key *skey)
@@ -2080,8 +2080,11 @@
 int des3_keysize(int *keysize)
 {
     LTC_ARGCHK(keysize != NULL);
-    if(*keysize < 24) {
-        return CRYPT_INVALID_KEYSIZE;
+    if (*keysize < 16)
+       return CRYPT_INVALID_KEYSIZE;
+    if (*keysize < 24) {
+       *keysize = 16;
+       return CRYPT_OK;
     }
     *keysize = 24;
     return CRYPT_OK;
--- a/libtomcrypt/src/ciphers/twofish/twofish.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/ciphers/twofish/twofish.c	Fri Jun 26 21:07:34 2020 +0800
@@ -7,9 +7,9 @@
  * guarantee it works.
  */
 
- /** 
+ /**
    @file twofish.c
-   Implementation of Twofish by Tom St Denis 
+   Implementation of Twofish by Tom St Denis
  */
 #include "tomcrypt.h"
 
@@ -145,14 +145,14 @@
    result = P[0] = B[0] = 0;
 
    /* unrolled branchless GF multiplier */
-   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1); 
-   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1); 
-   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1); 
-   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1); 
-   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1); 
-   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1); 
-   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1); 
-   result ^= B[a&1]; 
+   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1);
+   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1);
+   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1);
+   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1);
+   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1);
+   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1);
+   result ^= B[a&1]; a >>= 1;  B[1] = P[B[1]>>7] ^ (B[1] << 1);
+   result ^= B[a&1];
 
    return result;
 }
@@ -243,7 +243,7 @@
   unsigned char y[4];
   for (x = 0; x < 4; x++) {
       y[x] = in[x];
- }
+  }
   switch (k) {
      case 4:
             y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]);
@@ -439,7 +439,7 @@
    /* small ram variant */
    switch (k) {
          case 4 : skey->twofish.start = 0; break;
-         case 3 : skey->twofish.start = 1; break; 
+         case 3 : skey->twofish.start = 1; break;
          default: skey->twofish.start = 2; break;
    }
 #endif
@@ -473,18 +473,18 @@
     int r;
 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
     ulong32 *S1, *S2, *S3, *S4;
-#endif    
+#endif
 
     LTC_ARGCHK(pt   != NULL);
     LTC_ARGCHK(ct   != NULL);
     LTC_ARGCHK(skey != NULL);
-    
+
 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
     S1 = skey->twofish.S[0];
     S2 = skey->twofish.S[1];
     S3 = skey->twofish.S[2];
     S4 = skey->twofish.S[3];
-#endif    
+#endif
 
     LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
     LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
@@ -492,20 +492,20 @@
     b ^= skey->twofish.K[1];
     c ^= skey->twofish.K[2];
     d ^= skey->twofish.K[3];
-    
+
     k  = skey->twofish.K + 8;
     for (r = 8; r != 0; --r) {
         t2 = g1_func(b, skey);
         t1 = g_func(a, skey) + t2;
         c  = RORc(c ^ (t1 + k[0]), 1);
         d  = ROLc(d, 1) ^ (t2 + t1 + k[1]);
-        
+
         t2 = g1_func(d, skey);
         t1 = g_func(c, skey) + t2;
         a  = RORc(a ^ (t1 + k[2]), 1);
         b  = ROLc(b, 1) ^ (t2 + t1 + k[3]);
         k += 4;
-   }
+    }
 
     /* output with "undo last swap" */
     ta = c ^ skey->twofish.K[4];
@@ -533,7 +533,7 @@
   Decrypts a block of text with Twofish
   @param ct The input ciphertext (16 bytes)
   @param pt The output plaintext (16 bytes)
-  @param skey The key as scheduled 
+  @param skey The key as scheduled
   @return CRYPT_OK if successful
 */
 #ifdef LTC_CLEAN_STACK
@@ -546,18 +546,18 @@
     int r;
 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
     ulong32 *S1, *S2, *S3, *S4;
-#endif    
+#endif
 
     LTC_ARGCHK(pt   != NULL);
     LTC_ARGCHK(ct   != NULL);
     LTC_ARGCHK(skey != NULL);
-    
+
 #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
     S1 = skey->twofish.S[0];
     S2 = skey->twofish.S[1];
     S3 = skey->twofish.S[2];
     S4 = skey->twofish.S[3];
-#endif    
+#endif
 
     /* load input */
     LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]);
@@ -588,7 +588,7 @@
     b ^= skey->twofish.K[1];
     c ^= skey->twofish.K[2];
     d ^= skey->twofish.K[3];
-    
+
     /* store */
     STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
     STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
@@ -612,8 +612,8 @@
 {
  #ifndef LTC_TEST
     return CRYPT_NOP;
- #else    
- static const struct { 
+ #else
+ static const struct {
      int keylen;
      unsigned char key[32], pt[16], ct[16];
  } tests[] = {
@@ -633,7 +633,7 @@
        0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 },
      { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
        0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 }
-   }, { 
+   }, {
      32,
      { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
        0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
@@ -647,11 +647,11 @@
 };
 
 
- symmetric_key key;
- unsigned char tmp[2][16];
- int err, i, y;
- 
- for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
+  symmetric_key key;
+  unsigned char tmp[2][16];
+  int err, i, y;
+
+  for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
     if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
        return err;
     }
@@ -661,17 +661,17 @@
           compare_testvector(tmp[1], 16, tests[i].pt, 16, "Twofish Decrypt", i) != 0) {
        return CRYPT_FAIL_TESTVECTOR;
     }
-      /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
-      for (y = 0; y < 16; y++) tmp[0][y] = 0;
-      for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
-      for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key);
-      for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
- }    
- return CRYPT_OK;
-#endif 
+    /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
+    for (y = 0; y < 16; y++) tmp[0][y] = 0;
+    for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
+    for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key);
+    for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
+  }
+  return CRYPT_OK;
+#endif
 }
 
-/** Terminate the context 
+/** Terminate the context
    @param skey    The scheduled key
 */
 void twofish_done(symmetric_key *skey)
--- a/libtomcrypt/src/encauth/ccm/ccm_memory.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/encauth/ccm/ccm_memory.c	Fri Jun 26 21:07:34 2020 +0800
@@ -52,7 +52,7 @@
    int            err;
    unsigned long  len, L, x, y, z, CTRlen;
 #ifdef LTC_FAST
-   LTC_FAST_TYPE fastMask = ~0; /* initialize fastMask at all zeroes */
+   LTC_FAST_TYPE fastMask = ~(LTC_FAST_TYPE)0; /* initialize fastMask at all zeroes */
 #endif
    unsigned char mask = 0xff; /* initialize mask at all zeroes */
 
--- a/libtomcrypt/src/hashes/helper/hash_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/hashes/helper/hash_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -9,7 +9,7 @@
 #include "tomcrypt.h"
 
 #ifndef LTC_NO_FILE
-/** 
+/**
   @file hash_file.c
   Hash a file, Tom St Denis
 */
@@ -34,7 +34,7 @@
     }
 
     in = fopen(fname, "rb");
-    if (in == NULL) { 
+    if (in == NULL) {
        return CRYPT_FILE_NOTFOUND;
     }
 
--- a/libtomcrypt/src/hashes/helper/hash_filehandle.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/hashes/helper/hash_filehandle.c	Fri Jun 26 21:07:34 2020 +0800
@@ -14,13 +14,13 @@
    Hash open files, Tom St Denis
 */
 
-/** 
-  Hash data from an open file handle.  
+/**
+  Hash data from an open file handle.
   @param hash   The index of the hash you want to use
   @param in     The FILE* handle of the file you want to hash
   @param out    [out] The destination of the digest
   @param outlen [in/out] The max size and resulting size of the digest
-  @result CRYPT_OK if successful   
+  @result CRYPT_OK if successful
 */
 int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen)
 {
@@ -57,8 +57,8 @@
         }
     } while (x == LTC_FILE_READ_BUFSIZE);
     if ((err = hash_descriptor[hash].done(&md, out)) == CRYPT_OK) {
-    *outlen = hash_descriptor[hash].hashsize;
-        }
+       *outlen = hash_descriptor[hash].hashsize;
+    }
 
 LBL_CLEANBUF:
     zeromem(buf, LTC_FILE_READ_BUFSIZE);
--- a/libtomcrypt/src/headers/tomcrypt.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/headers/tomcrypt.h	Fri Jun 26 21:07:34 2020 +0800
@@ -27,14 +27,15 @@
 
 /* version */
 #define CRYPT   0x0118
-#define SCRYPT  "1.18.1"
+#define SCRYPT  "1.18.2"
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE  128
 
+#ifndef TAB_SIZE
 /* descriptor table size */
-/* Dropbear change - this should be smaller, saves some size */
-#define TAB_SIZE    5
+#define TAB_SIZE      32
+#endif
 
 /* error codes [will be expanded in future releases] */
 enum {
--- a/libtomcrypt/src/headers/tomcrypt_argchk.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/headers/tomcrypt_argchk.h	Fri Jun 26 21:07:34 2020 +0800
@@ -45,7 +45,7 @@
 
 #elif ARGTYPE == 3
 
-#define LTC_ARGCHK(x) 
+#define LTC_ARGCHK(x)
 #define LTC_ARGCHKVD(x) LTC_ARGCHK(x)
 
 #elif ARGTYPE == 4
--- a/libtomcrypt/src/headers/tomcrypt_custom.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/headers/tomcrypt_custom.h	Fri Jun 26 21:07:34 2020 +0800
@@ -74,8 +74,8 @@
   #define LTC_NO_MODES
   #define LTC_NO_HASHES
   #define LTC_NO_MACS
-   #define LTC_NO_PRNGS
-   #define LTC_NO_PK
+  #define LTC_NO_PRNGS
+  #define LTC_NO_PK
   #define LTC_NO_PKCS
   #define LTC_NO_MISC
 #endif /* LTC_NOTHING */
@@ -480,6 +480,13 @@
 #endif
 #endif
 
+#if defined(LTC_DER)
+   #ifndef LTC_DER_MAX_RECURSION
+      /* Maximum recursion limit when processing nested ASN.1 types. */
+      #define LTC_DER_MAX_RECURSION 30
+   #endif
+#endif
+
 #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT)
    /* Include the MPI functionality?  (required by the PK algorithms) */
    #define LTC_MPI
--- a/libtomcrypt/src/headers/tomcrypt_dropbear.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/headers/tomcrypt_dropbear.h	Fri Jun 26 21:07:34 2020 +0800
@@ -10,9 +10,9 @@
 #define LTC_SMALL_CODE
 #endif
 
-#if DROPBEAR_BLOWFISH
-#define LTC_BLOWFISH
-#endif
+/* Fewer entries needed */
+#define TAB_SIZE      5
+
 #if DROPBEAR_AES
 #define LTC_RIJNDAEL
 #endif
@@ -27,7 +27,7 @@
 #define LTC_DES
 #endif
 
-#if DROPBEAR_ENABLE_CTR_MODE
+#if DROPBEAR_ENABLE_CBC_MODE
 #define LTC_CBC_MODE
 #endif
 
@@ -35,6 +35,14 @@
 #define LTC_CTR_MODE
 #endif
 
+#if DROPBEAR_ENABLE_GCM_MODE
+#define LTC_GCM_MODE
+#endif
+
+#if DROPBEAR_CHACHA20POLY1305
+#define LTC_CHACHA
+#define LTC_POLY1305
+#endif
 
 #if DROPBEAR_SHA512
 #define LTC_SHA512
--- a/libtomcrypt/src/headers/tomcrypt_pk.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/headers/tomcrypt_pk.h	Fri Jun 26 21:07:34 2020 +0800
@@ -667,16 +667,16 @@
 
 /* UTF-8 */
 #if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(__WCHAR_MAX__) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR)
-#include <wchar.h>
-#if defined(__WCHAR_MAX__)
-#define LTC_WCHAR_MAX __WCHAR_MAX__
-#elif defined(WCHAR_MAX)
-#define LTC_WCHAR_MAX WCHAR_MAX
-#endif
+   #if defined(__WCHAR_MAX__)
+      #define LTC_WCHAR_MAX __WCHAR_MAX__
+   #else
+      #include <wchar.h>
+      #define LTC_WCHAR_MAX WCHAR_MAX
+   #endif
 /* please note that it might happen that LTC_WCHAR_MAX is undefined */
 #else
-typedef ulong32 wchar_t;
-#define LTC_WCHAR_MAX 0xFFFFFFFF
+   typedef ulong32 wchar_t;
+   #define LTC_WCHAR_MAX 0xFFFFFFFF
 #endif
 
 int der_encode_utf8_string(const wchar_t *in,  unsigned long inlen,
--- a/libtomcrypt/src/mac/blake2/blake2bmac_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/blake2/blake2bmac_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -23,6 +23,11 @@
 int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
 {
 #ifdef LTC_NO_FILE
+   LTC_UNUSED_PARAM(fname);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(mac);
+   LTC_UNUSED_PARAM(maclen);
    return CRYPT_NOP;
 #else
    blake2bmac_state st;
--- a/libtomcrypt/src/mac/blake2/blake2smac_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/blake2/blake2smac_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -23,6 +23,11 @@
 int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
 {
 #ifdef LTC_NO_FILE
+   LTC_UNUSED_PARAM(fname);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(mac);
+   LTC_UNUSED_PARAM(maclen);
    return CRYPT_NOP;
 #else
    blake2smac_state st;
--- a/libtomcrypt/src/mac/f9/f9_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/f9/f9_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -31,6 +31,12 @@
                     unsigned char *out, unsigned long *outlen)
 {
 #ifdef LTC_NO_FILE
+   LTC_UNUSED_PARAM(cipher);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(fname);
+   LTC_UNUSED_PARAM(out);
+   LTC_UNUSED_PARAM(outlen);
    return CRYPT_NOP;
 #else
    size_t x;
--- a/libtomcrypt/src/mac/hmac/hmac_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/hmac/hmac_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -30,7 +30,12 @@
                     unsigned char *out, unsigned long *outlen)
 {
 #ifdef LTC_NO_FILE
-    (void)hash; (void)fname; (void)key; (void)keylen; (void)out; (void)outlen;
+   LTC_UNUSED_PARAM(hash);
+   LTC_UNUSED_PARAM(fname);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(out);
+   LTC_UNUSED_PARAM(outlen);
     return CRYPT_NOP;
 #else
    hmac_state hmac;
--- a/libtomcrypt/src/mac/hmac/hmac_init.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/hmac/hmac_init.c	Fri Jun 26 21:07:34 2020 +0800
@@ -20,7 +20,7 @@
 /**
    Initialize an HMAC context.
    @param hmac     The HMAC state
-   @param hash     The index of the hash you want to use 
+   @param hash     The index of the hash you want to use
    @param key      The secret key
    @param keylen   The length of the secret key (octets)
    @return CRYPT_OK if successful
@@ -64,9 +64,9 @@
         XMEMCPY(hmac->key, key, (size_t)keylen);
     }
 
-        if(keylen < LTC_HMAC_BLOCKSIZE) {
-            zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen));
-        }
+    if(keylen < LTC_HMAC_BLOCKSIZE) {
+       zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen));
+    }
 
     /* Create the initialization vector for step (3) */
     for(i=0; i < LTC_HMAC_BLOCKSIZE;   i++) {
@@ -89,8 +89,8 @@
 #ifdef LTC_CLEAN_STACK
    zeromem(buf, LTC_HMAC_BLOCKSIZE);
 #endif
- 
-   return err;    
+
+   return err;
 }
 
 #endif
--- a/libtomcrypt/src/mac/omac/omac_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/omac/omac_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -31,6 +31,12 @@
                     unsigned char *out, unsigned long *outlen)
 {
 #ifdef LTC_NO_FILE
+   LTC_UNUSED_PARAM(cipher);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(filename);
+   LTC_UNUSED_PARAM(out);
+   LTC_UNUSED_PARAM(outlen);
    return CRYPT_NOP;
 #else
    size_t x;
--- a/libtomcrypt/src/mac/pmac/pmac_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/pmac/pmac_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -31,6 +31,12 @@
                     unsigned char *out, unsigned long *outlen)
 {
 #ifdef LTC_NO_FILE
+   LTC_UNUSED_PARAM(cipher);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(filename);
+   LTC_UNUSED_PARAM(out);
+   LTC_UNUSED_PARAM(outlen);
    return CRYPT_NOP;
 #else
    size_t x;
--- a/libtomcrypt/src/mac/poly1305/poly1305_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/poly1305/poly1305_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -28,6 +28,11 @@
 int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
 {
 #ifdef LTC_NO_FILE
+   LTC_UNUSED_PARAM(fname);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(mac);
+   LTC_UNUSED_PARAM(maclen);
    return CRYPT_NOP;
 #else
    poly1305_state st;
--- a/libtomcrypt/src/mac/xcbc/xcbc_file.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/mac/xcbc/xcbc_file.c	Fri Jun 26 21:07:34 2020 +0800
@@ -31,6 +31,12 @@
                     unsigned char *out, unsigned long *outlen)
 {
 #ifdef LTC_NO_FILE
+   LTC_UNUSED_PARAM(cipher);
+   LTC_UNUSED_PARAM(key);
+   LTC_UNUSED_PARAM(keylen);
+   LTC_UNUSED_PARAM(filename);
+   LTC_UNUSED_PARAM(out);
+   LTC_UNUSED_PARAM(outlen);
    return CRYPT_NOP;
 #else
    size_t x;
--- a/libtomcrypt/src/math/ltm_desc.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/math/ltm_desc.c	Fri Jun 26 21:07:34 2020 +0800
@@ -15,11 +15,14 @@
 #include <tommath.h>
 
 static const struct {
-    int mpi_code, ltc_code;
+    mp_err mpi_code;
+    int ltc_code;
 } mpi_to_ltc_codes[] = {
    { MP_OKAY ,  CRYPT_OK},
    { MP_MEM  ,  CRYPT_MEM},
    { MP_VAL  ,  CRYPT_INVALID_ARG},
+   { MP_ITER ,  CRYPT_INVALID_PACKET},
+   { MP_BUF  ,  CRYPT_BUFFER_OVERFLOW},
 };
 
 /**
@@ -27,11 +30,11 @@
    @param err    The error to convert
    @return The equivalent LTC error code or CRYPT_ERROR if none found
 */
-static int mpi_to_ltc_error(int err)
+static int mpi_to_ltc_error(mp_err err)
 {
-   int x;
+   size_t x;
 
-   for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
+   for (x = 0; x < sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0]); x++) {
        if (err == mpi_to_ltc_codes[x].mpi_code) {
           return mpi_to_ltc_codes[x].ltc_code;
        }
@@ -39,17 +42,27 @@
    return CRYPT_ERROR;
 }
 
+static int init_mpi(void **a)
+{
+   LTC_ARGCHK(a != NULL);
+
+   *a = XCALLOC(1, sizeof(mp_int));
+   if (*a == NULL) {
+      return CRYPT_MEM;
+   } else {
+      return CRYPT_OK;
+   }
+}
+
 static int init(void **a)
 {
    int err;
 
    LTC_ARGCHK(a != NULL);
 
-   *a = XCALLOC(1, sizeof(mp_int));
-   if (*a == NULL) {
-      return CRYPT_MEM;
+   if ((err = init_mpi(a)) != CRYPT_OK) {
+      return err;
    }
-
    if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) {
       XFREE(*a);
    }
@@ -79,23 +92,25 @@
 
 static int init_copy(void **a, void *b)
 {
-   if (init(a) != CRYPT_OK) {
-      return CRYPT_MEM;
-   }
-   return copy(b, *a);
+   int err;
+   LTC_ARGCHK(a  != NULL);
+   LTC_ARGCHK(b  != NULL);
+   if ((err = init_mpi(a)) != CRYPT_OK) return err;
+   return mpi_to_ltc_error(mp_init_copy(*a, b));
 }
 
 /* ---- trivial ---- */
 static int set_int(void *a, ltc_mp_digit b)
 {
    LTC_ARGCHK(a != NULL);
-   return mpi_to_ltc_error(mp_set_int(a, b));
+   mp_set_u32(a, b);
+   return CRYPT_OK;
 }
 
 static unsigned long get_int(void *a)
 {
    LTC_ARGCHK(a != NULL);
-   return mp_get_int(a);
+   return mp_get_ul(a);
 }
 
 static ltc_mp_digit get_digit(void *a, int n)
@@ -116,11 +131,9 @@
 
 static int compare(void *a, void *b)
 {
-   int ret;
    LTC_ARGCHK(a != NULL);
    LTC_ARGCHK(b != NULL);
-   ret = mp_cmp(a, b);
-   switch (ret) {
+   switch (mp_cmp(a, b)) {
       case MP_LT: return LTC_MP_LT;
       case MP_EQ: return LTC_MP_EQ;
       case MP_GT: return LTC_MP_GT;
@@ -130,10 +143,8 @@
 
 static int compare_d(void *a, ltc_mp_digit b)
 {
-   int ret;
    LTC_ARGCHK(a != NULL);
-   ret = mp_cmp_d(a, b);
-   switch (ret) {
+   switch (mp_cmp_d(a, b)) {
       case MP_LT: return LTC_MP_LT;
       case MP_EQ: return LTC_MP_EQ;
       case MP_GT: return LTC_MP_GT;
@@ -175,14 +186,14 @@
 {
    LTC_ARGCHK(a != NULL);
    LTC_ARGCHK(b != NULL);
-   return mpi_to_ltc_error(mp_toradix(a, b, radix));
+   return mpi_to_ltc_error(mp_to_radix(a, b, SIZE_MAX, NULL, radix));
 }
 
 /* get size as unsigned char string */
 static unsigned long unsigned_size(void *a)
 {
    LTC_ARGCHK(a != NULL);
-   return mp_unsigned_bin_size(a);
+   return (unsigned long)mp_ubin_size(a);
 }
 
 /* store */
@@ -190,7 +201,7 @@
 {
    LTC_ARGCHK(a != NULL);
    LTC_ARGCHK(b != NULL);
-   return mpi_to_ltc_error(mp_to_unsigned_bin(a, b));
+   return mpi_to_ltc_error(mp_to_ubin(a, b, SIZE_MAX, NULL));
 }
 
 /* read */
@@ -198,7 +209,7 @@
 {
    LTC_ARGCHK(a != NULL);
    LTC_ARGCHK(b != NULL);
-   return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len));
+   return mpi_to_ltc_error(mp_from_ubin(a, b, (size_t)len));
 }
 
 /* add */
@@ -403,9 +414,7 @@
    int err;
    LTC_ARGCHK(a != NULL);
    LTC_ARGCHK(c != NULL);
-   if (b == 0) {
-       b = LTC_MILLER_RABIN_REPS;
-   } /* if */
+   b = mp_prime_rabin_miller_trials(mp_count_bits(a));
    err = mpi_to_ltc_error(mp_prime_is_prime(a, b, c));
    *c = (*c == MP_YES) ? LTC_MP_YES : LTC_MP_NO;
    return err;
@@ -420,7 +429,7 @@
 const ltc_math_descriptor ltm_desc = {
 
    "LibTomMath",
-   (int)DIGIT_BIT,
+   (int)MP_DIGIT_BIT,
 
    &init,
    &init_copy,
--- a/libtomcrypt/src/math/multi.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/math/multi.c	Fri Jun 26 21:07:34 2020 +0800
@@ -67,7 +67,6 @@
       cur = va_arg(args, void**);
    }
    va_end(args);
-   return;
 }
 
 #endif
--- a/libtomcrypt/src/math/rand_bn.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/math/rand_bn.c	Fri Jun 26 21:07:34 2020 +0800
@@ -8,7 +8,7 @@
  */
 #include "tomcrypt.h"
 
-#ifdef LTC_MDSA
+#if defined(LTC_MDSA) || defined(LTC_MECC)
 /**
   Generate a random number N with given bitlength (note: MSB can be 0)
 */
--- a/libtomcrypt/src/misc/base64/base64_decode.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/misc/base64/base64_decode.c	Fri Jun 26 21:07:34 2020 +0800
@@ -43,8 +43,8 @@
 255, 255, 255, 255 };
 #endif /* LTC_BASE64 */
 
+#if defined(LTC_BASE64_URL)
 static const unsigned char map_base64url[] = {
-#if defined(LTC_BASE64_URL)
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
@@ -67,8 +67,8 @@
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255
+};
 #endif /* LTC_BASE64_URL */
-};
 
 enum {
    relaxed = 0,
@@ -117,8 +117,14 @@
    }
 
    if (y != 0) {
+      int allow_b64url = 0;
+#ifdef LTC_BASE64_URL
+      if (map == map_base64url) {
+        allow_b64url = 1;
+      }
+#endif
       if (y == 1) return CRYPT_INVALID_PACKET;
-      if ((y + g) != 4 && is_strict && map != map_base64url) return CRYPT_INVALID_PACKET;
+      if ((y + g) != 4 && is_strict && !allow_b64url) return CRYPT_INVALID_PACKET;
       t = t << (6 * (4 - y));
       if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW;
       if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255);
--- a/libtomcrypt/src/misc/crypt/crypt.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/misc/crypt/crypt.c	Fri Jun 26 21:07:34 2020 +0800
@@ -399,6 +399,7 @@
 #endif
 #if defined(LTC_DER)
     " DER "
+    " " NAME_VALUE(LTC_DER_MAX_RECURSION) " "
 #endif
 #if defined(LTC_PKCS_1)
     " PKCS#1 "
--- a/libtomcrypt/src/misc/crypt/crypt_constants.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/misc/crypt/crypt_constants.c	Fri Jun 26 21:07:34 2020 +0800
@@ -111,6 +111,7 @@
 
 #ifdef LTC_DER
 /* DER handling */
+    {"LTC_DER", 1},
     _C_STRINGIFY(LTC_ASN1_EOL),
     _C_STRINGIFY(LTC_ASN1_BOOLEAN),
     _C_STRINGIFY(LTC_ASN1_INTEGER),
@@ -132,6 +133,9 @@
     _C_STRINGIFY(LTC_ASN1_CONSTRUCTED),
     _C_STRINGIFY(LTC_ASN1_CONTEXT_SPECIFIC),
     _C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME),
+    _C_STRINGIFY(LTC_DER_MAX_RECURSION),
+#else
+    {"LTC_DER", 0},
 #endif
 
 #ifdef LTC_CTR_MODE
@@ -248,20 +252,16 @@
 int crypt_list_all_constants(char *names_list, unsigned int *names_list_size) {
     int i;
     unsigned int total_len = 0;
-    char number[32], *ptr;
+    char *ptr;
     int number_len;
     int count = sizeof(_crypt_constants) / sizeof(_crypt_constants[0]);
 
     /* calculate amount of memory required for the list */
     for (i=0; i<count; i++) {
-        total_len += (unsigned int)strlen(_crypt_constants[i].name) + 1;
-        /* the above +1 is for the commas */
-        number_len = snprintf(number, sizeof(number), "%d", _crypt_constants[i].value);
-        if ((number_len < 0) ||
-            ((unsigned int)number_len >= sizeof(number)))
+        number_len = snprintf(NULL, 0, "%s,%d\n", _crypt_constants[i].name, _crypt_constants[i].value);
+        if (number_len < 0)
           return -1;
-        total_len += number_len + 1;
-        /* this last +1 is for newlines (and ending NULL) */
+        total_len += number_len;
     }
 
     if (names_list == NULL) {
@@ -273,16 +273,11 @@
         /* build the names list */
         ptr = names_list;
         for (i=0; i<count; i++) {
-            strcpy(ptr, _crypt_constants[i].name);
-            ptr += strlen(_crypt_constants[i].name);
-            strcpy(ptr, ",");
-            ptr += 1;
-
-            number_len = snprintf(number, sizeof(number), "%d", _crypt_constants[i].value);
-            strcpy(ptr, number);
+            number_len = snprintf(ptr, total_len, "%s,%d\n", _crypt_constants[i].name, _crypt_constants[i].value);
+            if (number_len < 0) return -1;
+            if ((unsigned int)number_len > total_len) return -1;
+            total_len -= number_len;
             ptr += number_len;
-            strcpy(ptr, "\n");
-            ptr += 1;
         }
         /* to remove the trailing new-line */
         ptr -= 1;
--- a/libtomcrypt/src/misc/crypt/crypt_sizes.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/misc/crypt/crypt_sizes.c	Fri Jun 26 21:07:34 2020 +0800
@@ -307,19 +307,16 @@
 int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size) {
     int i;
     unsigned int total_len = 0;
-    char number[32], *ptr;
+    char *ptr;
     int number_len;
     int count = sizeof(_crypt_sizes) / sizeof(_crypt_sizes[0]);
 
     /* calculate amount of memory required for the list */
     for (i=0; i<count; i++) {
-        total_len += (unsigned int)strlen(_crypt_sizes[i].name) + 1;
-        /* the above +1 is for the commas */
-        number_len = snprintf(number, sizeof(number), "%u", _crypt_sizes[i].size);
-        if ((number_len < 0) ||
-            ((unsigned int)number_len >= sizeof(number)))
+        number_len = snprintf(NULL, 0, "%s,%u\n", _crypt_sizes[i].name, _crypt_sizes[i].size);
+        if (number_len < 0)
           return -1;
-        total_len += (unsigned int)strlen(number) + 1;
+        total_len += number_len;
         /* this last +1 is for newlines (and ending NULL) */
     }
 
@@ -332,16 +329,11 @@
         /* build the names list */
         ptr = names_list;
         for (i=0; i<count; i++) {
-            strcpy(ptr, _crypt_sizes[i].name);
-            ptr += strlen(_crypt_sizes[i].name);
-            strcpy(ptr, ",");
-            ptr += 1;
-
-            number_len = snprintf(number, sizeof(number), "%u", _crypt_sizes[i].size);
-            strcpy(ptr, number);
+            number_len = snprintf(ptr, total_len, "%s,%u\n", _crypt_sizes[i].name, _crypt_sizes[i].size);
+            if (number_len < 0) return -1;
+            if ((unsigned int)number_len > total_len) return -1;
+            total_len -= number_len;
             ptr += number_len;
-            strcpy(ptr, "\n");
-            ptr += 1;
         }
         /* to remove the trailing new-line */
         ptr -= 1;
--- a/libtomcrypt/src/modes/ctr/ctr_encrypt.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/modes/ctr/ctr_encrypt.c	Fri Jun 26 21:07:34 2020 +0800
@@ -17,47 +17,17 @@
 #ifdef LTC_CTR_MODE
 
 /**
-  CTR encrypt
+  CTR encrypt software implementation
   @param pt     Plaintext
   @param ct     [out] Ciphertext
   @param len    Length of plaintext (octets)
   @param ctr    CTR state
   @return CRYPT_OK if successful
 */
-int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
+static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
 {
    int x, err;
 
-   LTC_ARGCHK(pt != NULL);
-   LTC_ARGCHK(ct != NULL);
-   LTC_ARGCHK(ctr != NULL);
-
-   if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
-       return err;
-   }
-
-   /* is blocklen/padlen valid? */
-   if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) ||
-       ctr->padlen   < 0 || ctr->padlen   > (int)sizeof(ctr->pad)) {
-      return CRYPT_INVALID_ARG;
-   }
-
-#ifdef LTC_FAST
-   if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
-      return CRYPT_INVALID_ARG;
-   }
-#endif
-
-   /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
-   if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
-      if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
-         return err;
-      }
-      pt += (len / ctr->blocklen) * ctr->blocklen;
-      ct += (len / ctr->blocklen) * ctr->blocklen;
-      len %= ctr->blocklen;
-   }
-
    while (len) {
       /* is the pad empty? */
       if (ctr->padlen == ctr->blocklen) {
@@ -87,7 +57,7 @@
          ctr->padlen = 0;
       }
 #ifdef LTC_FAST
-      if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) {
+      if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) {
          for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
             *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^
                                                            *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));
@@ -105,6 +75,63 @@
    return CRYPT_OK;
 }
 
+/**
+  CTR encrypt
+  @param pt     Plaintext
+  @param ct     [out] Ciphertext
+  @param len    Length of plaintext (octets)
+  @param ctr    CTR state
+  @return CRYPT_OK if successful
+*/
+int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
+{
+   int err, fr;
+
+   LTC_ARGCHK(pt != NULL);
+   LTC_ARGCHK(ct != NULL);
+   LTC_ARGCHK(ctr != NULL);
+
+   if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
+       return err;
+   }
+
+   /* is blocklen/padlen valid? */
+   if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) ||
+       (ctr->padlen   < 0) || (ctr->padlen   > (int)sizeof(ctr->pad))) {
+      return CRYPT_INVALID_ARG;
+   }
+
+#ifdef LTC_FAST
+   if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
+      return CRYPT_INVALID_ARG;
+   }
+#endif
+
+   /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
+   if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) {
+     if (ctr->padlen < ctr->blocklen) {
+       fr = ctr->blocklen - ctr->padlen;
+       if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) {
+          return err;
+       }
+       pt += fr;
+       ct += fr;
+       len -= fr;
+     }
+
+     if (len >= (unsigned long)ctr->blocklen) {
+       if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
+          return err;
+       }
+       pt += (len / ctr->blocklen) * ctr->blocklen;
+       ct += (len / ctr->blocklen) * ctr->blocklen;
+       len %= ctr->blocklen;
+     }
+   }
+
+   return _ctr_encrypt(pt, ct, len, ctr);
+}
+
 #endif
 
 /* ref:         $Format:%D$ */
--- a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c	Fri Jun 26 21:07:34 2020 +0800
@@ -79,8 +79,8 @@
 */
 int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
 {
-   ltc_asn1_list *l;
-   unsigned long err, type, len, totlen, data_offset;
+   ltc_asn1_list *l, *t;
+   unsigned long err, type, len, totlen, data_offset, len_len;
    void          *realloc_tmp;
 
    LTC_ARGCHK(in    != NULL);
@@ -407,6 +407,17 @@
                 l->child->parent = l;
              }
 
+             t = l;
+             len_len = 0;
+             while((t != NULL) && (t->child != NULL)) {
+                len_len++;
+                t = t->child;
+             }
+             if (len_len > LTC_DER_MAX_RECURSION) {
+                err = CRYPT_ERROR;
+                goto error;
+             }
+
              break;
 
          case 0x80: /* Context-specific */
--- a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c	Fri Jun 26 21:07:34 2020 +0800
@@ -80,7 +80,7 @@
    }
 
    if ((alg_id[0].size != oid.OIDlen) ||
-        XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) {
+        XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0])) != 0) {
         /* OID mismatch */
         err = CRYPT_PK_INVALID_TYPE;
         goto LBL_ERR;
--- a/libtomcrypt/src/pk/dsa/dsa_export.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/dsa/dsa_export.c	Fri Jun 26 21:07:34 2020 +0800
@@ -69,7 +69,7 @@
       }
    } else {
       if (std) {
-          unsigned long tmplen = (mp_count_bits(key->y) / 8) + 8;
+          unsigned long tmplen = (unsigned long)(mp_count_bits(key->y) / 8) + 8;
           unsigned char* tmp = XMALLOC(tmplen);
           ltc_asn1_list int_list[3];
 
--- a/libtomcrypt/src/pk/dsa/dsa_generate_pqg.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/dsa/dsa_generate_pqg.c	Fri Jun 26 21:07:34 2020 +0800
@@ -72,8 +72,8 @@
   */
 
   seedbytes = group_size;
-  L = modulus_size * 8;
-  N = group_size * 8;
+  L = (unsigned long)modulus_size * 8;
+  N = (unsigned long)group_size * 8;
 
   /* XXX-TODO no Lucas test */
 #ifdef LTC_MPI_HAS_LUCAS_TEST
--- a/libtomcrypt/src/pk/ecc/ecc_sign_hash.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_sign_hash.c	Fri Jun 26 21:07:34 2020 +0800
@@ -14,14 +14,14 @@
 /**
   @file ecc_sign_hash.c
   ECC Crypto, Tom St Denis
-*/  
+*/
 
 static int _ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
-                        unsigned char *out, unsigned long *outlen, 
+                                unsigned char *out, unsigned long *outlen,
                                 prng_state *prng, int wprng, ecc_key *key, int sigformat)
 {
    ecc_key       pubkey;
-   void          *r, *s, *e, *p;
+   void          *r, *s, *e, *p, *b;
    int           err, max_iterations = LTC_PK_MAX_RETRIES;
    unsigned long pbits, pbytes, i, shift_right;
    unsigned char ch, buf[MAXBLOCKSIZE];
@@ -35,21 +35,21 @@
    if (key->type != PK_PRIVATE) {
       return CRYPT_PK_NOT_PRIVATE;
    }
-   
+
    /* is the IDX valid ?  */
    if (ltc_ecc_is_valid_idx(key->idx) != 1) {
       return CRYPT_PK_INVALID_TYPE;
    }
-   
+
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
       return err;
    }
 
    /* init the bignums */
-   if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { 
+   if ((err = mp_init_multi(&r, &s, &p, &e, &b, NULL)) != CRYPT_OK) {
       return err;
    }
-   if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)                      { goto errnokey; }
+   if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)              { goto errnokey; }
 
    /* get the hash and load it as a bignum into 'e' */
    pbits = mp_count_bits(p);
@@ -77,21 +77,24 @@
       }
 
       /* find r = x1 mod n */
-      if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK)                 { goto error; }
+      if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK)                          { goto error; }
 
       if (mp_iszero(r) == LTC_MP_YES) {
          ecc_free(&pubkey);
-      } else { 
-        /* find s = (e + xr)/k */
-        if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK)            { goto error; } /* k = 1/k */
-        if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK)                  { goto error; } /* s = xr */
-        if ((err = mp_add(e, s, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */
-        if ((err = mp_mod(s, p, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */
-        if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK)                { goto error; } /* s = (e + xr)/k */
-        ecc_free(&pubkey);
-        if (mp_iszero(s) == LTC_MP_NO) {
-           break;
-        }
+      } else {
+         if ((err = rand_bn_upto(b, p, prng, wprng)) != CRYPT_OK)          { goto error; } /* b = blinding value */
+         /* find s = (e + xr)/k */
+         if ((err = mp_mulmod(pubkey.k, b, p, pubkey.k)) != CRYPT_OK)      { goto error; } /* k = kb */
+         if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK)         { goto error; } /* k = 1/kb */
+         if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK)               { goto error; } /* s = xr */
+         if ((err = mp_mulmod(pubkey.k, s, p, s)) != CRYPT_OK)             { goto error; } /* s = xr/kb */
+         if ((err = mp_mulmod(pubkey.k, e, p, e)) != CRYPT_OK)             { goto error; } /* e = e/kb */
+         if ((err = mp_add(e, s, s)) != CRYPT_OK)                          { goto error; } /* s = e/kb + xr/kb */
+         if ((err = mp_mulmod(s, b, p, s)) != CRYPT_OK)                    { goto error; } /* s = b(e/kb + xr/kb) = (e + xr)/k */
+         ecc_free(&pubkey);
+         if (mp_iszero(s) == LTC_MP_NO) {
+            break;
+         }
       }
    } while (--max_iterations > 0);
 
@@ -112,17 +115,17 @@
    }
    else {
       /* store as ASN.1 SEQUENCE { r, s -- integer } */
-   err = der_encode_sequence_multi(out, outlen,
-                             LTC_ASN1_INTEGER, 1UL, r,
-                             LTC_ASN1_INTEGER, 1UL, s,
-                             LTC_ASN1_EOL, 0UL, NULL);
+      err = der_encode_sequence_multi(out, outlen,
+                               LTC_ASN1_INTEGER, 1UL, r,
+                               LTC_ASN1_INTEGER, 1UL, s,
+                               LTC_ASN1_EOL, 0UL, NULL);
    }
    goto errnokey;
 error:
    ecc_free(&pubkey);
 errnokey:
-   mp_clear_multi(r, s, p, e, NULL);
-   return err;   
+   mp_clear_multi(r, s, p, e, b, NULL);
+   return err;
 }
 
 /**
--- a/libtomcrypt/src/pk/ecc/ecc_verify_hash.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_verify_hash.c	Fri Jun 26 21:07:34 2020 +0800
@@ -14,10 +14,10 @@
 /**
   @file ecc_verify_hash.c
   ECC Crypto, Tom St Denis
-*/  
+*/
 
 static int _ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
-                    const unsigned char *hash, unsigned long hashlen, 
+                            const unsigned char *hash, unsigned long hashlen,
                             int *stat, ecc_key *key, int sigformat)
 {
    ecc_point    *mG, *mQ;
@@ -66,9 +66,9 @@
    }
    else {
       /* ASN.1 format */
-   if ((err = der_decode_sequence_multi(sig, siglen,
-                                  LTC_ASN1_INTEGER, 1UL, r,
-                                  LTC_ASN1_INTEGER, 1UL, s,
+      if ((err = der_decode_sequence_multi(sig, siglen,
+                                     LTC_ASN1_INTEGER, 1UL, r,
+                                     LTC_ASN1_INTEGER, 1UL, s,
                                      LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK)                             { goto error; }
    }
 
@@ -125,13 +125,13 @@
    if (ltc_mp.ecc_mul2add == NULL) {
       if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK)                                       { goto error; }
       if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK)                                       { goto error; }
-  
+
       /* find the montgomery mp */
       if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK)                                              { goto error; }
 
       /* add them */
       if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK)                                      { goto error; }
-   
+
       /* reduce */
       if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK)                                                { goto error; }
    } else {
@@ -153,7 +153,7 @@
    ltc_ecc_del_point(mG);
    ltc_ecc_del_point(mQ);
    mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
-   if (mp != NULL) { 
+   if (mp != NULL) {
       mp_montgomery_free(mp);
    }
    return err;
--- a/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c	Fri Jun 26 21:07:34 2020 +0800
@@ -17,7 +17,7 @@
 /**
   @file ltc_ecc_mulmod_timing.c
   ECC Crypto, Tom St Denis
-*/  
+*/
 
 #ifdef LTC_MECC
 
@@ -59,8 +59,8 @@
       return err;
    }
 
-  /* alloc ram for window temps */
-  for (i = 0; i < 3; i++) {
+   /* alloc ram for window temps */
+   for (i = 0; i < 3; i++) {
       M[i] = ltc_ecc_new_point();
       if (M[i] == NULL) {
          for (j = 0; j < i; j++) {
@@ -70,7 +70,7 @@
          mp_montgomery_free(mp);
          return CRYPT_MEM;
       }
-  }
+   }
 
    /* make a copy of G incase R==G */
    tG = ltc_ecc_new_point();
@@ -82,7 +82,7 @@
    if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK)                      { goto done; }
    mp_clear(mu);
    mu = NULL;
-   
+
    /* calc the M tab */
    /* M[0] == G */
    if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK)                                  { goto done; }
--- a/libtomcrypt/src/pk/rsa/rsa_export.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/rsa/rsa_export.c	Fri Jun 26 21:07:34 2020 +0800
@@ -58,7 +58,7 @@
       unsigned char* tmp = NULL;
 
       if (type & PK_STD) {
-          tmplen = (mp_count_bits(key->N)/8)*2+8;
+          tmplen = (unsigned long)(mp_count_bits(key->N) / 8) * 2 + 8;
           tmp = XMALLOC(tmplen);
           ptmplen = &tmplen;
           if (tmp == NULL) {
--- a/libtomcrypt/src/pk/rsa/rsa_import_pkcs8.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/pk/rsa/rsa_import_pkcs8.c	Fri Jun 26 21:07:34 2020 +0800
@@ -114,7 +114,7 @@
 
    /* check alg oid */
    if ((alg_seq[0].size != rsaoid.OIDlen) ||
-      XMEMCMP(rsaoid.OID, alg_seq[0].data, rsaoid.OIDlen * sizeof(rsaoid.OID[0]))) {
+      XMEMCMP(rsaoid.OID, alg_seq[0].data, rsaoid.OIDlen * sizeof(rsaoid.OID[0])) != 0) {
       err = CRYPT_PK_INVALID_TYPE;
       goto LBL_ERR;
    }
--- a/libtomcrypt/src/prngs/fortuna.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/prngs/fortuna.c	Fri Jun 26 21:07:34 2020 +0800
@@ -66,9 +66,9 @@
 {
    unsigned char tmp[MAXBLOCKSIZE];
    hash_state    md;
+   ulong64       reset_cnt;
    int           err, x;
 
-   ++prng->fortuna.reset_cnt;
 
    /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */
    sha256_init(&md);
@@ -77,8 +77,10 @@
       return err;
    }
 
+   reset_cnt = prng->fortuna.reset_cnt + 1;
+
    for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
-       if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) {
+       if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) {
           /* terminate this hash */
           if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) {
              sha256_done(&md, tmp);
@@ -108,9 +110,10 @@
    }
    _fortuna_update_iv(prng);
 
-   /* reset pool len */
+   /* reset/update internals */
    prng->fortuna.pool0_len = 0;
    prng->fortuna.wd        = 0;
+   prng->fortuna.reset_cnt = reset_cnt;
 
 
 #ifdef LTC_CLEAN_STACK
@@ -122,6 +125,46 @@
 }
 
 /**
+  "Update Seed File"-compliant update of K
+
+  @param in       The PRNG state
+  @param inlen    Size of the state
+  @param prng     The PRNG to import
+  @return CRYPT_OK if successful
+*/
+static int _fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state *prng)
+{
+   int           err;
+   unsigned char tmp[MAXBLOCKSIZE];
+   hash_state    md;
+
+   LTC_MUTEX_LOCK(&prng->lock);
+   /* new K = LTC_SHA256(K || in) */
+   sha256_init(&md);
+   if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) {
+      sha256_done(&md, tmp);
+      goto LBL_UNLOCK;
+   }
+   if ((err = sha256_process(&md, in, inlen)) != CRYPT_OK) {
+      sha256_done(&md, tmp);
+      goto LBL_UNLOCK;
+   }
+   /* finish key */
+   if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) {
+      goto LBL_UNLOCK;
+   }
+   _fortuna_update_iv(prng);
+
+LBL_UNLOCK:
+   LTC_MUTEX_UNLOCK(&prng->lock);
+#ifdef LTC_CLEAN_STACK
+   zeromem(&md, sizeof(md));
+#endif
+
+   return err;
+}
+
+/**
   Start the PRNG
   @param prng     [out] The PRNG state to initialize
   @return CRYPT_OK if successful
@@ -245,12 +288,17 @@
    }
 
    /* do we have to reseed? */
-   if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) {
+   if ((++prng->fortuna.wd == LTC_FORTUNA_WD) && (prng->fortuna.pool0_len >= 64)) {
       if (_fortuna_reseed(prng) != CRYPT_OK) {
          goto LBL_UNLOCK;
       }
    }
 
+   /* ensure that one reseed happened before allowing to read */
+   if (prng->fortuna.reset_cnt == 0) {
+      goto LBL_UNLOCK;
+   }
+
    /* now generate the blocks required */
    tlen = outlen;
 
@@ -404,10 +452,10 @@
 */
 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 {
-   int err, x;
+   int           err;
 
-   LTC_ARGCHK(in   != NULL);
-   LTC_ARGCHK(prng != NULL);
+   LTC_ARGCHK(in    != NULL);
+   LTC_ARGCHK(prng  != NULL);
 
    if (inlen < (unsigned long)fortuna_desc.export_size) {
       return CRYPT_INVALID_ARG;
@@ -416,12 +464,12 @@
    if ((err = fortuna_start(prng)) != CRYPT_OK) {
       return err;
    }
-   for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
-      if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) {
-         return err;
-      }
+
+   if ((err = _fortuna_update_seed(in, inlen, prng)) != CRYPT_OK) {
+      return err;
    }
-   return CRYPT_OK;
+
+   return err;
 }
 
 /**
--- a/libtomcrypt/src/prngs/sober128.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/src/prngs/sober128.c	Fri Jun 26 21:07:34 2020 +0800
@@ -189,7 +189,7 @@
    if (inlen < (unsigned long)sober128_desc.export_size) return CRYPT_INVALID_ARG;
 
    if ((err = sober128_start(prng)) != CRYPT_OK) return err;
-   if ((err = sober128_add_entropy(in, sober128_desc.export_size, prng)) != CRYPT_OK) return err;
+   if ((err = sober128_add_entropy(in, inlen, prng)) != CRYPT_OK) return err;
    return CRYPT_OK;
 }
 
--- a/libtomcrypt/tests/common.h	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/tests/common.h	Fri Jun 26 21:07:34 2020 +0800
@@ -16,9 +16,11 @@
 #ifdef LTC_VERBOSE
 #define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
 #define DOX(x, str) do { fprintf(stderr, "%s - %s:\n", #x, (str)); run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
+#define SHOULD_FAIL(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
 #else
 #define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
 #define DOX(x, str) do { run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
+#define SHOULD_FAIL(x) do { run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
 #endif
 
 void run_cmd(int res, int line, const char *file, const char *cmd, const char *algorithm);
--- a/libtomcrypt/tests/der_test.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtomcrypt/tests/der_test.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1094,6 +1094,25 @@
 }
 
 
+static void _der_recursion_limit(void)
+{
+   int failed = 0;
+   unsigned int n;
+   unsigned long integer = 123, s;
+   ltc_asn1_list seqs[LTC_DER_MAX_RECURSION + 2], dummy[1], *flexi;
+   unsigned char buf[2048];
+   LTC_SET_ASN1(dummy, 0, LTC_ASN1_SHORT_INTEGER, &integer, 1);
+   LTC_SET_ASN1(seqs, LTC_DER_MAX_RECURSION + 1, LTC_ASN1_SEQUENCE, dummy, 1);
+   for (n = 0; n < LTC_DER_MAX_RECURSION + 1; ++n) {
+      LTC_SET_ASN1(seqs, LTC_DER_MAX_RECURSION - n, LTC_ASN1_SEQUENCE, &seqs[LTC_DER_MAX_RECURSION - n + 1], 1);
+   }
+   s = sizeof(buf);
+   DO(der_encode_sequence(seqs, 1, buf, &s));
+   DO(der_decode_sequence(buf, s, seqs, 1));
+   SHOULD_FAIL(der_decode_sequence_flexi(buf, &s, &flexi));
+   if (failed) exit(EXIT_FAILURE);
+}
+
 int der_test(void)
 {
    unsigned long x, y, z, zz, oid[2][32];
@@ -1126,6 +1145,8 @@
    unsigned char utf8_buf[32];
    wchar_t utf8_out[32];
 
+
+   _der_recursion_limit();
    der_cacert_test();
 
    DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL));
--- a/libtommath/LICENSE	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/LICENSE	Fri Jun 26 21:07:34 2020 +0800
@@ -1,29 +1,26 @@
-LibTomMath is licensed under DUAL licensing terms.
+                          The LibTom license
 
-Choose and use the license of your needs.
-
-[LICENSE #1]
+This is free and unencumbered software released into the public domain.
 
-LibTomMath is public domain.  As should all quality software be.
-
-Tom St Denis
-
-[/LICENSE #1]
-
-[LICENSE #2]
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
 
-            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
-                    Version 2, December 2004
-
- Copyright (C) 2004 Sam Hocevar <[email protected]>
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
 
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
 
-            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. You just DO WHAT THE FUCK YOU WANT TO. 
-
-[/LICENSE #2]
+For more information, please refer to <http://unlicense.org/>
--- a/libtommath/Makefile.in	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/Makefile.in	Fri Jun 26 21:07:34 2020 +0800
@@ -7,6 +7,9 @@
 
 # So that libtommath can include Dropbear headers for options and m_burn()
 CFLAGS += -I$(srcdir) -I../libtomcrypt/src/headers/ -I$(srcdir)/../libtomcrypt/src/headers/ -I../ -I$(srcdir)/../
+CFLAGS += -Wno-deprecated
+
+V = 1
 
 ifeq ($V,1)
 silent=
@@ -23,44 +26,46 @@
 
 include $(srcdir)/makefile_include.mk
 
-%.o: %.c
+%.o: %.c $(HEADERS)
 ifneq ($V,1)
 	@echo "   * ${CC} $@"
 endif
-	${silent} ${CC} -c ${CFLAGS} $< -o $@
+	${silent} ${CC} -c ${LTM_CFLAGS} $< -o $@
 
 LCOV_ARGS=--directory .
 
 #START_INS
-OBJECTS=bncore.o bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \
-bn_fast_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o \
-bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o \
-bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o \
-bn_mp_div.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o bn_mp_exch.o \
-bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o bn_mp_exptmod_fast.o bn_mp_exteuclid.o \
-bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o \
-bn_mp_grow.o bn_mp_import.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \
-bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o \
-bn_mp_jacobi.o bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod_2d.o \
-bn_mp_mod.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
-bn_mp_montgomery_setup.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \
-bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_is_divisible.o \
+OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o bn_mp_addmod.o \
+bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
+bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
+bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
+bn_mp_error_to_string.o bn_mp_exch.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o bn_mp_fread.o \
+bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_i32.o bn_mp_get_i64.o \
+bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o bn_mp_get_mag_ul.o \
+bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_i32.o \
+bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_size.o \
+bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o bn_mp_invmod.o bn_mp_is_square.o \
+bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_log_u32.o bn_mp_lshd.o bn_mp_mod.o \
+bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
+bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \
+bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \
 bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \
-bn_mp_prime_rabin_miller_trials.o bn_mp_prime_random_ex.o bn_mp_radix_size.o bn_mp_radix_smap.o \
-bn_mp_rand.o bn_mp_read_radix.o bn_mp_read_signed_bin.o bn_mp_read_unsigned_bin.o bn_mp_reduce_2k.o \
-bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce.o \
-bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \
-bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o bn_mp_signed_bin_size.o bn_mp_sqr.o bn_mp_sqrmod.o \
-bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_toom_mul.o \
-bn_mp_toom_sqr.o bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_to_signed_bin.o bn_mp_to_signed_bin_n.o \
-bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o \
-bn_prime_tab.o bn_reverse.o bn_s_mp_add.o bn_s_mp_exptmod.o bn_s_mp_mul_digs.o bn_s_mp_mul_high_digs.o \
-bn_s_mp_sqr.o bn_s_mp_sub.o
+bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \
+bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \
+bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \
+bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o \
+bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \
+bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o \
+bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o \
+bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o \
+bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
+bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
+bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \
+bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
 
 #END_INS
 
-$(OBJECTS): $(HEADERS)
-
 $(LIBNAME):  $(OBJECTS)
 	$(AR) $(ARFLAGS) $@ $(OBJECTS)
 	$(RANLIB) $@
@@ -73,20 +78,20 @@
 # So far I've seen improvements in the MP math
 profiled:
 	make CFLAGS="$(CFLAGS) -fprofile-arcs -DTESTING" timing
-	./ltmtest
-	rm -f *.a *.o ltmtest
+	./timing
+	rm -f *.a *.o timing
 	make CFLAGS="$(CFLAGS) -fbranch-probabilities"
 
 #make a single object profiled library
 profiled_single:
 	perl gen.pl
-	$(CC) $(CFLAGS) -fprofile-arcs -DTESTING -c mpi.c -o mpi.o
-	$(CC) $(CFLAGS) -DTESTING -DTIMER demo/timing.c mpi.o -lgcov -o ltmtest
-	./ltmtest
-	rm -f *.o ltmtest
-	$(CC) $(CFLAGS) -fbranch-probabilities -DTESTING -c mpi.c -o mpi.o
+	$(CC) $(LTM_CFLAGS) -fprofile-arcs -DTESTING -c mpi.c -o mpi.o
+	$(CC) $(LTM_CFLAGS) -DTESTING -DTIMER demo/timing.c mpi.o -lgcov -o timing
+	./timing
+	rm -f *.o timing
+	$(CC) $(LTM_CFLAGS) -fbranch-probabilities -DTESTING -c mpi.c -o mpi.o
 	$(AR) $(ARFLAGS) $(LIBNAME) mpi.o
-	$(RANLIB) $(LIBNAME)	
+	ranlib $(LIBNAME)
 
 install: $(LIBNAME)
 	install -d $(DESTDIR)$(LIBPATH)
@@ -98,41 +103,45 @@
 	rm $(DESTDIR)$(LIBPATH)/$(LIBNAME)
 	rm $(HEADERS_PUB:%=$(DESTDIR)$(INCPATH)/%)
 
-test: $(LIBNAME) demo/demo.o
-	$(CC) $(CFLAGS) demo/demo.o $(LIBNAME) $(LFLAGS) -o test
+test_standalone: test
+	@echo "test_standalone is deprecated, please use make-target 'test'"
+
+DEMOS=test mtest_opponent
 
-test_standalone: $(LIBNAME) demo/demo.o
-	$(CC) $(CFLAGS) demo/demo.o $(LIBNAME) $(LFLAGS) -o test
+define DEMO_template
+$(1): demo/$(1).o demo/shared.o $$(LIBNAME)
+	$$(CC) $$(LTM_CFLAGS) $$(LTM_LFLAGS) $$^ -o $$@
+endef
+
+$(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo))))
 
 .PHONY: mtest
 mtest:
-	cd mtest ; $(CC) $(CFLAGS) -O0 mtest.c $(LFLAGS) -o mtest
+	cd mtest ; $(CC) $(LTM_CFLAGS) -O0 mtest.c $(LTM_LFLAGS) -o mtest
 
-travis_mtest: test mtest
-	@ for i in `seq 1 10` ; do sleep 500 && echo alive; done &
-	./mtest/mtest 666666 | ./test > test.log
+timing: $(LIBNAME) demo/timing.c
+	$(CC) $(LTM_CFLAGS) -DTIMER demo/timing.c $(LIBNAME) $(LTM_LFLAGS) -o timing
 
-timing: $(LIBNAME)
-	$(CC) $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME) $(LFLAGS) -o ltmtest
+tune: $(LIBNAME)
+	$(MAKE) -C etc tune CFLAGS="$(LTM_CFLAGS)"
+	$(MAKE)
 
 # You have to create a file .coveralls.yml with the content "repo_token: <the token>"
 # in the base folder to be able to submit to coveralls
 coveralls: lcov
 	coveralls-lcov
 
-docdvi poster docs mandvi manual:
+docs manual:
 	$(MAKE) -C doc/ $@ V=$(V)
 
-pretty:
-	perl pretty.build
-
 .PHONY: pre_gen
 pre_gen:
+	mkdir -p pre_gen
 	perl gen.pl
 	sed -e 's/[[:blank:]]*$$//' mpi.c > pre_gen/mpi.c
 	rm mpi.c
 
-zipup: clean pre_gen new_file manual poster docs
+zipup: clean astyle new_file docs
 	@# Update the index, so diff-index won't fail in case the pdf has been created.
 	@#   As the pdf creation modifies the tex files, git sometimes detects the
 	@#   modified files, but misses that it's put back to its original version.
@@ -141,17 +150,24 @@
 	rm -rf libtommath-$(VERSION) ltm-$(VERSION).*
 	@# files/dirs excluded from "git archive" are defined in .gitattributes
 	git archive --format=tar --prefix=libtommath-$(VERSION)/ HEAD | tar x
+	@echo 'fixme check'
+	-@(find libtommath-$(VERSION)/ -type f | xargs grep 'FIXM[E]') && echo '############## BEWARE: the "fixme" marker was found !!! ##############' || true
 	mkdir -p libtommath-$(VERSION)/doc
-	cp doc/bn.pdf doc/tommath.pdf doc/poster.pdf libtommath-$(VERSION)/doc/
+	cp doc/bn.pdf libtommath-$(VERSION)/doc/
+	$(MAKE) -C libtommath-$(VERSION)/ pre_gen
 	tar -c libtommath-$(VERSION)/ | xz -6e -c - > ltm-$(VERSION).tar.xz
 	zip -9rq ltm-$(VERSION).zip libtommath-$(VERSION)
+	cp doc/bn.pdf bn-$(VERSION).pdf
 	rm -rf libtommath-$(VERSION)
 	gpg -b -a ltm-$(VERSION).tar.xz
 	gpg -b -a ltm-$(VERSION).zip
 
 new_file:
-	bash updatemakes.sh
-	perl dep.pl
+	perl helper.pl --update-files
 
 perlcritic:
-	perlcritic *.pl
+	perlcritic *.pl doc/*.pl
+
+astyle:
+	@echo "   * run astyle on all sources"
+	@astyle --options=astylerc --formatted $(OBJECTS:.o=.c) tommath*.h demo/*.c etc/*.c mtest/mtest.c
--- a/libtommath/README.md	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/README.md	Fri Jun 26 21:07:34 2020 +0800
@@ -1,15 +1,44 @@
-[![Build Status - master](https://travis-ci.org/libtom/libtommath.png?branch=master)](https://travis-ci.org/libtom/libtommath)
+# libtommath
+
+This is the git repository for [LibTomMath](http://www.libtom.net/LibTomMath/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C.
+
+## Build Status
+
+### Travis CI
+
+master: [![Build Status](https://api.travis-ci.org/libtom/libtommath.png?branch=master)](https://travis-ci.org/libtom/libtommath)
+
+develop: [![Build Status](https://api.travis-ci.org/libtom/libtommath.png?branch=develop)](https://travis-ci.org/libtom/libtommath)
 
-[![Build Status - develop](https://travis-ci.org/libtom/libtommath.png?branch=develop)](https://travis-ci.org/libtom/libtommath)
+### AppVeyor
+
+master: [![Build status](https://ci.appveyor.com/api/projects/status/b80lpolw3i8m6hsh/branch/master?svg=true)](https://ci.appveyor.com/project/libtom/libtommath/branch/master)
+
+develop: [![Build status](https://ci.appveyor.com/api/projects/status/b80lpolw3i8m6hsh/branch/develop?svg=true)](https://ci.appveyor.com/project/libtom/libtommath/branch/develop)
 
-This is the git repository for [LibTomMath](http://www.libtom.org/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C.
+### ABI Laboratory
+
+API/ABI changes: [check here](https://abi-laboratory.pro/tracker/timeline/libtommath/)
+
+## Summary
 
 The `develop` branch contains the in-development version. Stable releases are tagged.
 
-Documentation is built from the LaTeX file `bn.tex`. There is also limited documentation in `tommath.h`. There is also a document, `tommath.pdf`, which describes the goals of the project and many of the algorithms used.
+Documentation is built from the LaTeX file `bn.tex`. There is also limited documentation in `tommath.h`.
+There is also a document, `tommath.pdf`, which describes the goals of the project and many of the algorithms used.
 
-The project can be build by using `make`. Along with the usual `make`, `make clean` and `make install`, there are several other build targets, see the makefile for details. There are also makefiles for certain specific platforms.
+The project can be build by using `make`. Along with the usual `make`, `make clean` and `make install`,
+there are several other build targets, see the makefile for details.
+There are also makefiles for certain specific platforms.
+
+## Testing
 
 Tests are located in `demo/` and can be built in two flavors.
-* `make test` creates a test binary that is intended to be run against `mtest`. `mtest` can be built with `make mtest` and test execution is done like `./mtest/mtest | ./test`. `mtest` is creating test vectors using an alternative MPI library and `test` is consuming these vectors to verify correct behavior of ltm
-* `make test_standalone` creates a stand-alone test binary that executes several test routines.
+* `make test` creates a stand-alone test binary that executes several test routines.
+* `make mtest_opponent` creates a test binary that is intended to be run against `mtest`.
+  `mtest` can be built with `make mtest` and test execution is done like `./mtest/mtest | ./mtest_opponent`.
+  `mtest` is creating test vectors using an alternative MPI library and `test` is consuming these vectors to verify correct behavior of ltm
+
+## Building and Installing
+
+Building is straightforward for GNU Linux only, the section "Building LibTomMath" in the documentation in `doc/bn.pdf` has the details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/astylerc	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,30 @@
+# Artistic Style, see http://astyle.sourceforge.net/
+# full documentation, see: http://astyle.sourceforge.net/astyle.html
+#
+# usage:
+#       astyle --options=astylerc *.[ch]
+
+# Do not create backup, annonying in the times of git
+suffix=none
+
+## Bracket Style Options
+style=kr
+
+## Tab Options
+indent=spaces=3
+
+## Bracket Modify Options
+
+## Indentation Options
+min-conditional-indent=0
+
+## Padding Options
+pad-header
+unpad-paren
+align-pointer=name
+
+## Formatting Options
+break-after-logical
+max-code-length=120
+convert-tabs
+mode=c
--- a/libtommath/bn.tex	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1913 +0,0 @@
-\documentclass[synpaper]{book}
-\usepackage{hyperref}
-\usepackage{makeidx}
-\usepackage{amssymb}
-\usepackage{color}
-\usepackage{alltt}
-\usepackage{graphicx}
-\usepackage{layout}
-\def\union{\cup}
-\def\intersect{\cap}
-\def\getsrandom{\stackrel{\rm R}{\gets}}
-\def\cross{\times}
-\def\cat{\hspace{0.5em} \| \hspace{0.5em}}
-\def\catn{$\|$}
-\def\divides{\hspace{0.3em} | \hspace{0.3em}}
-\def\nequiv{\not\equiv}
-\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}}
-\def\lcm{{\rm lcm}}
-\def\gcd{{\rm gcd}}
-\def\log{{\rm log}}
-\def\ord{{\rm ord}}
-\def\abs{{\mathit abs}}
-\def\rep{{\mathit rep}}
-\def\mod{{\mathit\ mod\ }}
-\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})}
-\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor}
-\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
-\def\Or{{\rm\ or\ }}
-\def\And{{\rm\ and\ }}
-\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}}
-\def\implies{\Rightarrow}
-\def\undefined{{\rm ``undefined"}}
-\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}}
-\let\oldphi\phi
-\def\phi{\varphi}
-\def\Pr{{\rm Pr}}
-\newcommand{\str}[1]{{\mathbf{#1}}}
-\def\F{{\mathbb F}}
-\def\N{{\mathbb N}}
-\def\Z{{\mathbb Z}}
-\def\R{{\mathbb R}}
-\def\C{{\mathbb C}}
-\def\Q{{\mathbb Q}}
-\definecolor{DGray}{gray}{0.5}
-\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
-\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
-\def\gap{\vspace{0.5ex}}
-\makeindex
-\begin{document}
-\frontmatter
-\pagestyle{empty}
-\title{LibTomMath User Manual \\ v1.0}
-\author{Tom St Denis \\ [email protected]}
-\maketitle
-This text, the library and the accompanying textbook are all hereby placed in the public domain.  This book has been
-formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package.
-
-\vspace{10cm}
-
-\begin{flushright}Open Source.  Open Academia.  Open Minds.
-
-\mbox{ }
-
-Tom St Denis,
-
-Ontario, Canada
-\end{flushright}
-
-\tableofcontents
-\listoffigures
-\mainmatter
-\pagestyle{headings}
-\chapter{Introduction}
-\section{What is LibTomMath?}
-LibTomMath is a library of source code which provides a series of efficient and carefully written functions for manipulating
-large integer numbers.  It was written in portable ISO C source code so that it will build on any platform with a conforming
-C compiler.
-
-In a nutshell the library was written from scratch with verbose comments to help instruct computer science students how
-to implement ``bignum'' math.  However, the resulting code has proven to be very useful.  It has been used by numerous
-universities, commercial and open source software developers.  It has been used on a variety of platforms ranging from
-Linux and Windows based x86 to ARM based Gameboys and PPC based MacOS machines.
-
-\section{License}
-As of the v0.25 the library source code has been placed in the public domain with every new release.  As of the v0.28
-release the textbook ``Implementing Multiple Precision Arithmetic'' has been placed in the public domain with every new
-release as well.  This textbook is meant to compliment the project by providing a more solid walkthrough of the development
-algorithms used in the library.
-
-Since both\footnote{Note that the MPI files under mtest/ are copyrighted by Michael Fromberger.  They are not required to use LibTomMath.} are in the
-public domain everyone is entitled to do with them as they see fit.
-
-\section{Building LibTomMath}
-
-LibTomMath is meant to be very ``GCC friendly'' as it comes with a makefile well suited for GCC.  However, the library will
-also build in MSVC, Borland C out of the box.  For any other ISO C compiler a makefile will have to be made by the end
-developer.
-
-\subsection{Static Libraries}
-To build as a static library for GCC issue the following
-\begin{alltt}
-make
-\end{alltt}
-
-command.  This will build the library and archive the object files in ``libtommath.a''.  Now you link against
-that and include ``tommath.h'' within your programs.  Alternatively to build with MSVC issue the following
-\begin{alltt}
-nmake -f makefile.msvc
-\end{alltt}
-
-This will build the library and archive the object files in ``tommath.lib''.  This has been tested with MSVC
-version 6.00 with service pack 5.
-
-\subsection{Shared Libraries}
-To build as a shared library for GCC issue the following
-\begin{alltt}
-make -f makefile.shared
-\end{alltt}
-This requires the ``libtool'' package (common on most Linux/BSD systems).  It will build LibTomMath as both shared
-and static then install (by default) into /usr/lib as well as install the header files in /usr/include.  The shared
-library (resource) will be called ``libtommath.la'' while the static library called ``libtommath.a''.  Generally
-you use libtool to link your application against the shared object.
-
-There is limited support for making a ``DLL'' in windows via the ``makefile.cygwin\_dll'' makefile.  It requires
-Cygwin to work with since it requires the auto-export/import functionality.  The resulting DLL and import library
-``libtommath.dll.a'' can be used to link LibTomMath dynamically to any Windows program using Cygwin.
-
-\subsection{Testing}
-To build the library and the test harness type
-
-\begin{alltt}
-make test
-\end{alltt}
-
-This will build the library, ``test'' and ``mtest/mtest''.  The ``test'' program will accept test vectors and verify the
-results.  ``mtest/mtest'' will generate test vectors using the MPI library by Michael Fromberger\footnote{A copy of MPI
-is included in the package}.  Simply pipe mtest into test using
-
-\begin{alltt}
-mtest/mtest | test
-\end{alltt}
-
-If you do not have a ``/dev/urandom'' style RNG source you will have to write your own PRNG and simply pipe that into
-mtest.  For example, if your PRNG program is called ``myprng'' simply invoke
-
-\begin{alltt}
-myprng | mtest/mtest | test
-\end{alltt}
-
-This will output a row of numbers that are increasing.  Each column is a different test (such as addition, multiplication, etc)
-that is being performed.  The numbers represent how many times the test was invoked.  If an error is detected the program
-will exit with a dump of the relevent numbers it was working with.
-
-\section{Build Configuration}
-LibTomMath can configured at build time in three phases we shall call ``depends'', ``tweaks'' and ``trims''.
-Each phase changes how the library is built and they are applied one after another respectively.
-
-To make the system more powerful you can tweak the build process.  Classes are defined in the file
-``tommath\_superclass.h''.  By default, the symbol ``LTM\_ALL'' shall be defined which simply
-instructs the system to build all of the functions.  This is how LibTomMath used to be packaged.  This will give you
-access to every function LibTomMath offers.
-
-However, there are cases where such a build is not optional.  For instance, you want to perform RSA operations.  You
-don't need the vast majority of the library to perform these operations.  Aside from LTM\_ALL there is
-another pre--defined class ``SC\_RSA\_1'' which works in conjunction with the RSA from LibTomCrypt.  Additional
-classes can be defined base on the need of the user.
-
-\subsection{Build Depends}
-In the file tommath\_class.h you will see a large list of C ``defines'' followed by a series of ``ifdefs''
-which further define symbols.  All of the symbols (technically they're macros $\ldots$) represent a given C source
-file.  For instance, BN\_MP\_ADD\_C represents the file ``bn\_mp\_add.c''.  When a define has been enabled the
-function in the respective file will be compiled and linked into the library.  Accordingly when the define
-is absent the file will not be compiled and not contribute any size to the library.
-
-You will also note that the header tommath\_class.h is actually recursively included (it includes itself twice).
-This is to help resolve as many dependencies as possible.  In the last pass the symbol LTM\_LAST will be defined.
-This is useful for ``trims''.
-
-\subsection{Build Tweaks}
-A tweak is an algorithm ``alternative''.  For example, to provide tradeoffs (usually between size and space).
-They can be enabled at any pass of the configuration phase.
-
-\begin{small}
-\begin{center}
-\begin{tabular}{|l|l|}
-\hline \textbf{Define} & \textbf{Purpose} \\
-\hline BN\_MP\_DIV\_SMALL & Enables a slower, smaller and equally \\
-                          & functional mp\_div() function \\
-\hline
-\end{tabular}
-\end{center}
-\end{small}
-
-\subsection{Build Trims}
-A trim is a manner of removing functionality from a function that is not required.  For instance, to perform
-RSA cryptography you only require exponentiation with odd moduli so even moduli support can be safely removed.
-Build trims are meant to be defined on the last pass of the configuration which means they are to be defined
-only if LTM\_LAST has been defined.
-
-\subsubsection{Moduli Related}
-\begin{small}
-\begin{center}
-\begin{tabular}{|l|l|}
-\hline \textbf{Restriction} & \textbf{Undefine} \\
-\hline Exponentiation with odd moduli only & BN\_S\_MP\_EXPTMOD\_C \\
-                                           & BN\_MP\_REDUCE\_C \\
-                                           & BN\_MP\_REDUCE\_SETUP\_C \\
-                                           & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\
-                                           & BN\_FAST\_S\_MP\_MUL\_HIGH\_DIGS\_C \\
-\hline Exponentiation with random odd moduli & (The above plus the following) \\
-                                           & BN\_MP\_REDUCE\_2K\_C \\
-                                           & BN\_MP\_REDUCE\_2K\_SETUP\_C \\
-                                           & BN\_MP\_REDUCE\_IS\_2K\_C \\
-                                           & BN\_MP\_DR\_IS\_MODULUS\_C \\
-                                           & BN\_MP\_DR\_REDUCE\_C \\
-                                           & BN\_MP\_DR\_SETUP\_C \\
-\hline Modular inverse odd moduli only     & BN\_MP\_INVMOD\_SLOW\_C \\
-\hline Modular inverse (both, smaller/slower) & BN\_FAST\_MP\_INVMOD\_C \\
-\hline
-\end{tabular}
-\end{center}
-\end{small}
-
-\subsubsection{Operand Size Related}
-\begin{small}
-\begin{center}
-\begin{tabular}{|l|l|}
-\hline \textbf{Restriction} & \textbf{Undefine} \\
-\hline Moduli $\le 2560$ bits              & BN\_MP\_MONTGOMERY\_REDUCE\_C \\
-                                           & BN\_S\_MP\_MUL\_DIGS\_C \\
-                                           & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\
-                                           & BN\_S\_MP\_SQR\_C \\
-\hline Polynomial Schmolynomial            & BN\_MP\_KARATSUBA\_MUL\_C \\
-                                           & BN\_MP\_KARATSUBA\_SQR\_C \\
-                                           & BN\_MP\_TOOM\_MUL\_C \\
-                                           & BN\_MP\_TOOM\_SQR\_C \\
-
-\hline
-\end{tabular}
-\end{center}
-\end{small}
-
-
-\section{Purpose of LibTomMath}
-Unlike  GNU MP (GMP) Library, LIP, OpenSSL or various other commercial kits (Miracl), LibTomMath was not written with
-bleeding edge performance in mind.  First and foremost LibTomMath was written to be entirely open.  Not only is the
-source code public domain (unlike various other GPL/etc licensed code), not only is the code freely downloadable but the
-source code is also accessible for computer science students attempting to learn ``BigNum'' or multiple precision
-arithmetic techniques.
-
-LibTomMath was written to be an instructive collection of source code.  This is why there are many comments, only one
-function per source file and often I use a ``middle-road'' approach where I don't cut corners for an extra 2\% speed
-increase.
-
-Source code alone cannot really teach how the algorithms work which is why I also wrote a textbook that accompanies
-the library (beat that!).
-
-So you may be thinking ``should I use LibTomMath?'' and the answer is a definite maybe.  Let me tabulate what I think
-are the pros and cons of LibTomMath by comparing it to the math routines from GnuPG\footnote{GnuPG v1.2.3 versus LibTomMath v0.28}.
-
-\newpage\begin{figure}[here]
-\begin{small}
-\begin{center}
-\begin{tabular}{|l|c|c|l|}
-\hline \textbf{Criteria} & \textbf{Pro} & \textbf{Con} & \textbf{Notes} \\
-\hline Few lines of code per file & X & & GnuPG $ = 300.9$, LibTomMath  $ = 71.97$ \\
-\hline Commented function prototypes & X && GnuPG function names are cryptic. \\
-\hline Speed && X & LibTomMath is slower.  \\
-\hline Totally free & X & & GPL has unfavourable restrictions.\\
-\hline Large function base & X & & GnuPG is barebones. \\
-\hline Five modular reduction algorithms & X & & Faster modular exponentiation for a variety of moduli. \\
-\hline Portable & X & & GnuPG requires configuration to build. \\
-\hline
-\end{tabular}
-\end{center}
-\end{small}
-\caption{LibTomMath Valuation}
-\end{figure}
-
-It may seem odd to compare LibTomMath to GnuPG since the math in GnuPG is only a small portion of the entire application.
-However, LibTomMath was written with cryptography in mind.  It provides essentially all of the functions a cryptosystem
-would require when working with large integers.
-
-So it may feel tempting to just rip the math code out of GnuPG (or GnuMP where it was taken from originally) in your
-own application but I think there are reasons not to.  While LibTomMath is slower than libraries such as GnuMP it is
-not normally significantly slower.  On x86 machines the difference is normally a factor of two when performing modular
-exponentiations.  It depends largely on the processor, compiler and the moduli being used.
-
-Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern.  However,
-on the other side of the coin LibTomMath offers you a totally free (public domain) well structured math library
-that is very flexible, complete and performs well in resource contrained environments.  Fast RSA for example can
-be performed with as little as 8KB of ram for data (again depending on build options).
-
-\chapter{Getting Started with LibTomMath}
-\section{Building Programs}
-In order to use LibTomMath you must include ``tommath.h'' and link against the appropriate library file (typically
-libtommath.a).  There is no library initialization required and the entire library is thread safe.
-
-\section{Return Codes}
-There are three possible return codes a function may return.
-
-\index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM}
-\begin{figure}[here!]
-\begin{center}
-\begin{small}
-\begin{tabular}{|l|l|}
-\hline \textbf{Code} & \textbf{Meaning} \\
-\hline MP\_OKAY & The function succeeded. \\
-\hline MP\_VAL  & The function input was invalid. \\
-\hline MP\_MEM  & Heap memory exhausted. \\
-\hline &\\
-\hline MP\_YES  & Response is yes. \\
-\hline MP\_NO   & Response is no. \\
-\hline
-\end{tabular}
-\end{small}
-\end{center}
-\caption{Return Codes}
-\end{figure}
-
-The last two codes listed are not actually ``return'ed'' by a function.  They are placed in an integer (the caller must
-provide the address of an integer it can store to) which the caller can access.  To convert one of the three return codes
-to a string use the following function.
-
-\index{mp\_error\_to\_string}
-\begin{alltt}
-char *mp_error_to_string(int code);
-\end{alltt}
-
-This will return a pointer to a string which describes the given error code.  It will not work for the return codes
-MP\_YES and MP\_NO.
-
-\section{Data Types}
-The basic ``multiple precision integer'' type is known as the ``mp\_int'' within LibTomMath.  This data type is used to
-organize all of the data required to manipulate the integer it represents.  Within LibTomMath it has been prototyped
-as the following.
-
-\index{mp\_int}
-\begin{alltt}
-typedef struct  \{
-    int used, alloc, sign;
-    mp_digit *dp;
-\} mp_int;
-\end{alltt}
-
-Where ``mp\_digit'' is a data type that represents individual digits of the integer.  By default, an mp\_digit is the
-ISO C ``unsigned long'' data type and each digit is $28-$bits long.  The mp\_digit type can be configured to suit other
-platforms by defining the appropriate macros.
-
-All LTM functions that use the mp\_int type will expect a pointer to mp\_int structure.  You must allocate memory to
-hold the structure itself by yourself (whether off stack or heap it doesn't matter).  The very first thing that must be
-done to use an mp\_int is that it must be initialized.
-
-\section{Function Organization}
-
-The arithmetic functions of the library are all organized to have the same style prototype.  That is source operands
-are passed on the left and the destination is on the right.  For instance,
-
-\begin{alltt}
-mp_add(&a, &b, &c);       /* c = a + b */
-mp_mul(&a, &a, &c);       /* c = a * a */
-mp_div(&a, &b, &c, &d);   /* c = [a/b], d = a mod b */
-\end{alltt}
-
-Another feature of the way the functions have been implemented is that source operands can be destination operands as well.
-For instance,
-
-\begin{alltt}
-mp_add(&a, &b, &b);       /* b = a + b */
-mp_div(&a, &b, &a, &c);   /* a = [a/b], c = a mod b */
-\end{alltt}
-
-This allows operands to be re-used which can make programming simpler.
-
-\section{Initialization}
-\subsection{Single Initialization}
-A single mp\_int can be initialized with the ``mp\_init'' function.
-
-\index{mp\_init}
-\begin{alltt}
-int mp_init (mp_int * a);
-\end{alltt}
-
-This function expects a pointer to an mp\_int structure and will initialize the members of the structure so the mp\_int
-represents the default integer which is zero.  If the functions returns MP\_OKAY then the mp\_int is ready to be used
-by the other LibTomMath functions.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* use the number */
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-\subsection{Single Free}
-When you are finished with an mp\_int it is ideal to return the heap it used back to the system.  The following function
-provides this functionality.
-
-\index{mp\_clear}
-\begin{alltt}
-void mp_clear (mp_int * a);
-\end{alltt}
-
-The function expects a pointer to a previously initialized mp\_int structure and frees the heap it uses.  It sets the
-pointer\footnote{The ``dp'' member.} within the mp\_int to \textbf{NULL} which is used to prevent double free situations.
-Is is legal to call mp\_clear() twice on the same mp\_int in a row.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* use the number */
-
-   /* We're done with it. */
-   mp_clear(&number);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-\subsection{Multiple Initializations}
-Certain algorithms require more than one large integer.  In these instances it is ideal to initialize all of the mp\_int
-variables in an ``all or nothing'' fashion.  That is, they are either all initialized successfully or they are all
-not initialized.
-
-The  mp\_init\_multi() function provides this functionality.
-
-\index{mp\_init\_multi} \index{mp\_clear\_multi}
-\begin{alltt}
-int mp_init_multi(mp_int *mp, ...);
-\end{alltt}
-
-It accepts a \textbf{NULL} terminated list of pointers to mp\_int structures.  It will attempt to initialize them all
-at once.  If the function returns MP\_OKAY then all of the mp\_int variables are ready to use, otherwise none of them
-are available for use.  A complementary mp\_clear\_multi() function allows multiple mp\_int variables to be free'd
-from the heap at the same time.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int num1, num2, num3;
-   int result;
-
-   if ((result = mp_init_multi(&num1,
-                               &num2,
-                               &num3, NULL)) != MP\_OKAY) \{
-      printf("Error initializing the numbers.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* use the numbers */
-
-   /* We're done with them. */
-   mp_clear_multi(&num1, &num2, &num3, NULL);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-\subsection{Other Initializers}
-To initialized and make a copy of an mp\_int the mp\_init\_copy() function has been provided.
-
-\index{mp\_init\_copy}
-\begin{alltt}
-int mp_init_copy (mp_int * a, mp_int * b);
-\end{alltt}
-
-This function will initialize $a$ and make it a copy of $b$ if all goes well.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int num1, num2;
-   int result;
-
-   /* initialize and do work on num1 ... */
-
-   /* We want a copy of num1 in num2 now */
-   if ((result = mp_init_copy(&num2, &num1)) != MP_OKAY) \{
-     printf("Error initializing the copy.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* now num2 is ready and contains a copy of num1 */
-
-   /* We're done with them. */
-   mp_clear_multi(&num1, &num2, NULL);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-Another less common initializer is mp\_init\_size() which allows the user to initialize an mp\_int with a given
-default number of digits.  By default, all initializers allocate \textbf{MP\_PREC} digits.  This function lets
-you override this behaviour.
-
-\index{mp\_init\_size}
-\begin{alltt}
-int mp_init_size (mp_int * a, int size);
-\end{alltt}
-
-The $size$ parameter must be greater than zero.  If the function succeeds the mp\_int $a$ will be initialized
-to have $size$ digits (which are all initially zero).
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   /* we need a 60-digit number */
-   if ((result = mp_init_size(&number, 60)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* use the number */
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-\section{Maintenance Functions}
-
-\subsection{Reducing Memory Usage}
-When an mp\_int is in a state where it won't be changed again\footnote{A Diffie-Hellman modulus for instance.} excess
-digits can be removed to return memory to the heap with the mp\_shrink() function.
-
-\index{mp\_shrink}
-\begin{alltt}
-int mp_shrink (mp_int * a);
-\end{alltt}
-
-This will remove excess digits of the mp\_int $a$.  If the operation fails the mp\_int should be intact without the
-excess digits being removed.  Note that you can use a shrunk mp\_int in further computations, however, such operations
-will require heap operations which can be slow.  It is not ideal to shrink mp\_int variables that you will further
-modify in the system (unless you are seriously low on memory).
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* use the number [e.g. pre-computation]  */
-
-   /* We're done with it for now. */
-   if ((result = mp_shrink(&number)) != MP_OKAY) \{
-      printf("Error shrinking the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* use it .... */
-
-
-   /* we're done with it. */
-   mp_clear(&number);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-\subsection{Adding additional digits}
-
-Within the mp\_int structure are two parameters which control the limitations of the array of digits that represent
-the integer the mp\_int is meant to equal.   The \textit{used} parameter dictates how many digits are significant, that is,
-contribute to the value of the mp\_int.  The \textit{alloc} parameter dictates how many digits are currently available in
-the array.  If you need to perform an operation that requires more digits you will have to mp\_grow() the mp\_int to
-your desired size.
-
-\index{mp\_grow}
-\begin{alltt}
-int mp_grow (mp_int * a, int size);
-\end{alltt}
-
-This will grow the array of digits of $a$ to $size$.  If the \textit{alloc} parameter is already bigger than
-$size$ the function will not do anything.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* use the number */
-
-   /* We need to add 20 digits to the number  */
-   if ((result = mp_grow(&number, number.alloc + 20)) != MP_OKAY) \{
-      printf("Error growing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-
-   /* use the number */
-
-   /* we're done with it. */
-   mp_clear(&number);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-\chapter{Basic Operations}
-\section{Small Constants}
-Setting mp\_ints to small constants is a relatively common operation.  To accomodate these instances there are two
-small constant assignment functions.  The first function is used to set a single digit constant while the second sets
-an ISO C style ``unsigned long'' constant.  The reason for both functions is efficiency.  Setting a single digit is quick but the
-domain of a digit can change (it's always at least $0 \ldots 127$).
-
-\subsection{Single Digit}
-
-Setting a single digit can be accomplished with the following function.
-
-\index{mp\_set}
-\begin{alltt}
-void mp_set (mp_int * a, mp_digit b);
-\end{alltt}
-
-This will zero the contents of $a$ and make it represent an integer equal to the value of $b$.  Note that this
-function has a return type of \textbf{void}.  It cannot cause an error so it is safe to assume the function
-succeeded.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* set the number to 5 */
-   mp_set(&number, 5);
-
-   /* we're done with it. */
-   mp_clear(&number);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-\subsection{Long Constants}
-
-To set a constant that is the size of an ISO C ``unsigned long'' and larger than a single digit the following function
-can be used.
-
-\index{mp\_set\_int}
-\begin{alltt}
-int mp_set_int (mp_int * a, unsigned long b);
-\end{alltt}
-
-This will assign the value of the 32-bit variable $b$ to the mp\_int $a$.  Unlike mp\_set() this function will always
-accept a 32-bit input regardless of the size of a single digit.  However, since the value may span several digits
-this function can fail if it runs out of heap memory.
-
-To get the ``unsigned long'' copy of an mp\_int the following function can be used.
-
-\index{mp\_get\_int}
-\begin{alltt}
-unsigned long mp_get_int (mp_int * a);
-\end{alltt}
-
-This will return the 32 least significant bits of the mp\_int $a$.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* set the number to 654321 (note this is bigger than 127) */
-   if ((result = mp_set_int(&number, 654321)) != MP_OKAY) \{
-      printf("Error setting the value of the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   printf("number == \%lu", mp_get_int(&number));
-
-   /* we're done with it. */
-   mp_clear(&number);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-This should output the following if the program succeeds.
-
-\begin{alltt}
-number == 654321
-\end{alltt}
-
-\subsection{Long Constants - platform dependant}
-
-\index{mp\_set\_long}
-\begin{alltt}
-int mp_set_long (mp_int * a, unsigned long b);
-\end{alltt}
-
-This will assign the value of the platform-dependant sized variable $b$ to the mp\_int $a$.
-
-To get the ``unsigned long'' copy of an mp\_int the following function can be used.
-
-\index{mp\_get\_long}
-\begin{alltt}
-unsigned long mp_get_long (mp_int * a);
-\end{alltt}
-
-This will return the least significant bits of the mp\_int $a$ that fit into an ``unsigned long''.
-
-\subsection{Long Long Constants}
-
-\index{mp\_set\_long\_long}
-\begin{alltt}
-int mp_set_long_long (mp_int * a, unsigned long long b);
-\end{alltt}
-
-This will assign the value of the 64-bit variable $b$ to the mp\_int $a$.
-
-To get the ``unsigned long long'' copy of an mp\_int the following function can be used.
-
-\index{mp\_get\_long\_long}
-\begin{alltt}
-unsigned long long mp_get_long_long (mp_int * a);
-\end{alltt}
-
-This will return the 64 least significant bits of the mp\_int $a$.
-
-\subsection{Initialize and Setting Constants}
-To both initialize and set small constants the following two functions are available.
-\index{mp\_init\_set} \index{mp\_init\_set\_int}
-\begin{alltt}
-int mp_init_set (mp_int * a, mp_digit b);
-int mp_init_set_int (mp_int * a, unsigned long b);
-\end{alltt}
-
-Both functions work like the previous counterparts except they first mp\_init $a$ before setting the values.
-
-\begin{alltt}
-int main(void)
-\{
-   mp_int number1, number2;
-   int    result;
-
-   /* initialize and set a single digit */
-   if ((result = mp_init_set(&number1, 100)) != MP_OKAY) \{
-      printf("Error setting number1: \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* initialize and set a long */
-   if ((result = mp_init_set_int(&number2, 1023)) != MP_OKAY) \{
-      printf("Error setting number2: \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* display */
-   printf("Number1, Number2 == \%lu, \%lu",
-          mp_get_int(&number1), mp_get_int(&number2));
-
-   /* clear */
-   mp_clear_multi(&number1, &number2, NULL);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt}
-
-If this program succeeds it shall output.
-\begin{alltt}
-Number1, Number2 == 100, 1023
-\end{alltt}
-
-\section{Comparisons}
-
-Comparisons in LibTomMath are always performed in a ``left to right'' fashion.  There are three possible return codes
-for any comparison.
-
-\index{MP\_GT} \index{MP\_EQ} \index{MP\_LT}
-\begin{figure}[here]
-\begin{center}
-\begin{tabular}{|c|c|}
-\hline \textbf{Result Code} & \textbf{Meaning} \\
-\hline MP\_GT & $a > b$ \\
-\hline MP\_EQ & $a = b$ \\
-\hline MP\_LT & $a < b$ \\
-\hline
-\end{tabular}
-\end{center}
-\caption{Comparison Codes for $a, b$}
-\label{fig:CMP}
-\end{figure}
-
-In figure \ref{fig:CMP} two integers $a$ and $b$ are being compared.  In this case $a$ is said to be ``to the left'' of
-$b$.
-
-\subsection{Unsigned comparison}
-
-An unsigned comparison considers only the digits themselves and not the associated \textit{sign} flag of the
-mp\_int structures.  This is analogous to an absolute comparison.  The function mp\_cmp\_mag() will compare two
-mp\_int variables based on their digits only.
-
-\index{mp\_cmp\_mag}
-\begin{alltt}
-int mp_cmp_mag(mp_int * a, mp_int * b);
-\end{alltt}
-This will compare $a$ to $b$ placing $a$ to the left of $b$.  This function cannot fail and will return one of the
-three compare codes listed in figure \ref{fig:CMP}.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number1, number2;
-   int result;
-
-   if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{
-      printf("Error initializing the numbers.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* set the number1 to 5 */
-   mp_set(&number1, 5);
-
-   /* set the number2 to -6 */
-   mp_set(&number2, 6);
-   if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{
-      printf("Error negating number2.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   switch(mp_cmp_mag(&number1, &number2)) \{
-       case MP_GT:  printf("|number1| > |number2|"); break;
-       case MP_EQ:  printf("|number1| = |number2|"); break;
-       case MP_LT:  printf("|number1| < |number2|"); break;
-   \}
-
-   /* we're done with it. */
-   mp_clear_multi(&number1, &number2, NULL);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes
-successfully it should print the following.
-
-\begin{alltt}
-|number1| < |number2|
-\end{alltt}
-
-This is because $\vert -6 \vert = 6$ and obviously $5 < 6$.
-
-\subsection{Signed comparison}
-
-To compare two mp\_int variables based on their signed value the mp\_cmp() function is provided.
-
-\index{mp\_cmp}
-\begin{alltt}
-int mp_cmp(mp_int * a, mp_int * b);
-\end{alltt}
-
-This will compare $a$ to the left of $b$.  It will first compare the signs of the two mp\_int variables.  If they
-differ it will return immediately based on their signs.  If the signs are equal then it will compare the digits
-individually.  This function will return one of the compare conditions codes listed in figure \ref{fig:CMP}.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number1, number2;
-   int result;
-
-   if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{
-      printf("Error initializing the numbers.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* set the number1 to 5 */
-   mp_set(&number1, 5);
-
-   /* set the number2 to -6 */
-   mp_set(&number2, 6);
-   if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{
-      printf("Error negating number2.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   switch(mp_cmp(&number1, &number2)) \{
-       case MP_GT:  printf("number1 > number2"); break;
-       case MP_EQ:  printf("number1 = number2"); break;
-       case MP_LT:  printf("number1 < number2"); break;
-   \}
-
-   /* we're done with it. */
-   mp_clear_multi(&number1, &number2, NULL);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes
-successfully it should print the following.
-
-\begin{alltt}
-number1 > number2
-\end{alltt}
-
-\subsection{Single Digit}
-
-To compare a single digit against an mp\_int the following function has been provided.
-
-\index{mp\_cmp\_d}
-\begin{alltt}
-int mp_cmp_d(mp_int * a, mp_digit b);
-\end{alltt}
-
-This will compare $a$ to the left of $b$ using a signed comparison.  Note that it will always treat $b$ as
-positive.  This function is rather handy when you have to compare against small values such as $1$ (which often
-comes up in cryptography).  The function cannot fail and will return one of the tree compare condition codes
-listed in figure \ref{fig:CMP}.
-
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* set the number to 5 */
-   mp_set(&number, 5);
-
-   switch(mp_cmp_d(&number, 7)) \{
-       case MP_GT:  printf("number > 7"); break;
-       case MP_EQ:  printf("number = 7"); break;
-       case MP_LT:  printf("number < 7"); break;
-   \}
-
-   /* we're done with it. */
-   mp_clear(&number);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-If this program functions properly it will print out the following.
-
-\begin{alltt}
-number < 7
-\end{alltt}
-
-\section{Logical Operations}
-
-Logical operations are operations that can be performed either with simple shifts or boolean operators such as
-AND, XOR and OR directly.  These operations are very quick.
-
-\subsection{Multiplication by two}
-
-Multiplications and divisions by any power of two can be performed with quick logical shifts either left or
-right depending on the operation.
-
-When multiplying or dividing by two a special case routine can be used which are as follows.
-\index{mp\_mul\_2} \index{mp\_div\_2}
-\begin{alltt}
-int mp_mul_2(mp_int * a, mp_int * b);
-int mp_div_2(mp_int * a, mp_int * b);
-\end{alltt}
-
-The former will assign twice $a$ to $b$ while the latter will assign half $a$ to $b$.  These functions are fast
-since the shift counts and maskes are hardcoded into the routines.
-
-\begin{small} \begin{alltt}
-int main(void)
-\{
-   mp_int number;
-   int result;
-
-   if ((result = mp_init(&number)) != MP_OKAY) \{
-      printf("Error initializing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* set the number to 5 */
-   mp_set(&number, 5);
-
-   /* multiply by two */
-   if ((result = mp\_mul\_2(&number, &number)) != MP_OKAY) \{
-      printf("Error multiplying the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-   switch(mp_cmp_d(&number, 7)) \{
-       case MP_GT:  printf("2*number > 7"); break;
-       case MP_EQ:  printf("2*number = 7"); break;
-       case MP_LT:  printf("2*number < 7"); break;
-   \}
-
-   /* now divide by two */
-   if ((result = mp\_div\_2(&number, &number)) != MP_OKAY) \{
-      printf("Error dividing the number.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-   switch(mp_cmp_d(&number, 7)) \{
-       case MP_GT:  printf("2*number/2 > 7"); break;
-       case MP_EQ:  printf("2*number/2 = 7"); break;
-       case MP_LT:  printf("2*number/2 < 7"); break;
-   \}
-
-   /* we're done with it. */
-   mp_clear(&number);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt} \end{small}
-
-If this program is successful it will print out the following text.
-
-\begin{alltt}
-2*number > 7
-2*number/2 < 7
-\end{alltt}
-
-Since $10 > 7$ and $5 < 7$.
-
-To multiply by a power of two the following function can be used.
-
-\index{mp\_mul\_2d}
-\begin{alltt}
-int mp_mul_2d(mp_int * a, int b, mp_int * c);
-\end{alltt}
-
-This will multiply $a$ by $2^b$ and store the result in ``c''.  If the value of $b$ is less than or equal to
-zero the function will copy $a$ to ``c'' without performing any further actions.  The multiplication itself
-is implemented as a right-shift operation of $a$ by $b$ bits.
-
-To divide by a power of two use the following.
-
-\index{mp\_div\_2d}
-\begin{alltt}
-int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d);
-\end{alltt}
-Which will divide $a$ by $2^b$, store the quotient in ``c'' and the remainder in ``d'.  If $b \le 0$ then the
-function simply copies $a$ over to ``c'' and zeroes $d$.  The variable $d$ may be passed as a \textbf{NULL}
-value to signal that the remainder is not desired.  The division itself is implemented as a left-shift
-operation of $a$ by $b$ bits.
-
-\subsection{Polynomial Basis Operations}
-
-Strictly speaking the organization of the integers within the mp\_int structures is what is known as a
-``polynomial basis''.  This simply means a field element is stored by divisions of a radix.  For example, if
-$f(x) = \sum_{i=0}^{k} y_ix^k$ for any vector $\vec y$ then the array of digits in $\vec y$ are said to be
-the polynomial basis representation of $z$ if $f(\beta) = z$ for a given radix $\beta$.
-
-To multiply by the polynomial $g(x) = x$ all you have todo is shift the digits of the basis left one place.  The
-following function provides this operation.
-
-\index{mp\_lshd}
-\begin{alltt}
-int mp_lshd (mp_int * a, int b);
-\end{alltt}
-
-This will multiply $a$ in place by $x^b$ which is equivalent to shifting the digits left $b$ places and inserting zeroes
-in the least significant digits.  Similarly to divide by a power of $x$ the following function is provided.
-
-\index{mp\_rshd}
-\begin{alltt}
-void mp_rshd (mp_int * a, int b)
-\end{alltt}
-This will divide $a$ in place by $x^b$ and discard the remainder.  This function cannot fail as it performs the operations
-in place and no new digits are required to complete it.
-
-\subsection{AND, OR and XOR Operations}
-
-While AND, OR and XOR operations are not typical ``bignum functions'' they can be useful in several instances.  The
-three functions are prototyped as follows.
-
-\index{mp\_or} \index{mp\_and} \index{mp\_xor}
-\begin{alltt}
-int mp_or  (mp_int * a, mp_int * b, mp_int * c);
-int mp_and (mp_int * a, mp_int * b, mp_int * c);
-int mp_xor (mp_int * a, mp_int * b, mp_int * c);
-\end{alltt}
-
-Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR.
-
-\section{Addition and Subtraction}
-
-To compute an addition or subtraction the following two functions can be used.
-
-\index{mp\_add} \index{mp\_sub}
-\begin{alltt}
-int mp_add (mp_int * a, mp_int * b, mp_int * c);
-int mp_sub (mp_int * a, mp_int * b, mp_int * c)
-\end{alltt}
-
-Which perform $c = a \odot b$ where $\odot$ is one of signed addition or subtraction.  The operations are fully sign
-aware.
-
-\section{Sign Manipulation}
-\subsection{Negation}
-\label{sec:NEG}
-Simple integer negation can be performed with the following.
-
-\index{mp\_neg}
-\begin{alltt}
-int mp_neg (mp_int * a, mp_int * b);
-\end{alltt}
-
-Which assigns $-a$ to $b$.
-
-\subsection{Absolute}
-Simple integer absolutes can be performed with the following.
-
-\index{mp\_neg}
-\begin{alltt}
-int mp_abs (mp_int * a, mp_int * b);
-\end{alltt}
-
-Which assigns $\vert a \vert$ to $b$.
-
-\section{Integer Division and Remainder}
-To perform a complete and general integer division with remainder use the following function.
-
-\index{mp\_div}
-\begin{alltt}
-int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
-\end{alltt}
-
-This divides $a$ by $b$ and stores the quotient in $c$ and $d$.  The signed quotient is computed such that
-$bc + d = a$.  Note that either of $c$ or $d$ can be set to \textbf{NULL} if their value is not required.  If
-$b$ is zero the function returns \textbf{MP\_VAL}.
-
-
-\chapter{Multiplication and Squaring}
-\section{Multiplication}
-A full signed integer multiplication can be performed with the following.
-\index{mp\_mul}
-\begin{alltt}
-int mp_mul (mp_int * a, mp_int * b, mp_int * c);
-\end{alltt}
-Which assigns the full signed product $ab$ to $c$.  This function actually breaks into one of four cases which are
-specific multiplication routines optimized for given parameters.  First there are the Toom-Cook multiplications which
-should only be used with very large inputs.  This is followed by the Karatsuba multiplications which are for moderate
-sized inputs.  Then followed by the Comba and baseline multipliers.
-
-Fortunately for the developer you don't really need to know this unless you really want to fine tune the system.  mp\_mul()
-will determine on its own\footnote{Some tweaking may be required.} what routine to use automatically when it is called.
-
-\begin{alltt}
-int main(void)
-\{
-   mp_int number1, number2;
-   int result;
-
-   /* Initialize the numbers */
-   if ((result = mp_init_multi(&number1,
-                               &number2, NULL)) != MP_OKAY) \{
-      printf("Error initializing the numbers.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* set the terms */
-   if ((result = mp_set_int(&number, 257)) != MP_OKAY) \{
-      printf("Error setting number1.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   if ((result = mp_set_int(&number2, 1023)) != MP_OKAY) \{
-      printf("Error setting number2.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* multiply them */
-   if ((result = mp_mul(&number1, &number2,
-                        &number1)) != MP_OKAY) \{
-      printf("Error multiplying terms.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* display */
-   printf("number1 * number2 == \%lu", mp_get_int(&number1));
-
-   /* free terms and return */
-   mp_clear_multi(&number1, &number2, NULL);
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt}
-
-If this program succeeds it shall output the following.
-
-\begin{alltt}
-number1 * number2 == 262911
-\end{alltt}
-
-\section{Squaring}
-Since squaring can be performed faster than multiplication it is performed it's own function instead of just using
-mp\_mul().
-
-\index{mp\_sqr}
-\begin{alltt}
-int mp_sqr (mp_int * a, mp_int * b);
-\end{alltt}
-
-Will square $a$ and store it in $b$.  Like the case of multiplication there are four different squaring
-algorithms all which can be called from mp\_sqr().  It is ideal to use mp\_sqr over mp\_mul when squaring terms because
-of the speed difference.
-
-\section{Tuning Polynomial Basis Routines}
-
-Both of the Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that
-the Comba and baseline algorithms use.  At $O(n^{1.464973})$ and $O(n^{1.584962})$ running times respectively they require
-considerably less work.  For example, a 10000-digit multiplication would take roughly 724,000 single precision
-multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor
-of 138).
-
-So why not always use Karatsuba or Toom-Cook?   The simple answer is that they have so much overhead that they're not
-actually faster than Comba until you hit distinct  ``cutoff'' points.  For Karatsuba with the default configuration,
-GCC 3.3.1 and an Athlon XP processor the cutoff point is roughly 110 digits (about 70 for the Intel P4).  That is, at
-110 digits Karatsuba and Comba multiplications just about break even and for 110+ digits Karatsuba is faster.
-
-Toom-Cook has incredible overhead and is probably only useful for very large inputs.  So far no known cutoff points
-exist and for the most part I just set the cutoff points very high to make sure they're not called.
-
-A demo program in the ``etc/'' directory of the project called ``tune.c'' can be used to find the cutoff points.  This
-can be built with GCC as follows
-
-\begin{alltt}
-make XXX
-\end{alltt}
-Where ``XXX'' is one of the following entries from the table \ref{fig:tuning}.
-
-\begin{figure}[here]
-\begin{center}
-\begin{small}
-\begin{tabular}{|l|l|}
-\hline \textbf{Value of XXX} & \textbf{Meaning} \\
-\hline tune & Builds portable tuning application \\
-\hline tune86 & Builds x86 (pentium and up) program for COFF \\
-\hline tune86c & Builds x86 program for Cygwin \\
-\hline tune86l & Builds x86 program for Linux (ELF format) \\
-\hline
-\end{tabular}
-\end{small}
-\end{center}
-\caption{Build Names for Tuning Programs}
-\label{fig:tuning}
-\end{figure}
-
-When the program is running it will output a series of measurements for different cutoff points.  It will first find
-good Karatsuba squaring and multiplication points.  Then it proceeds to find Toom-Cook points.  Note that the Toom-Cook
-tuning takes a very long time as the cutoff points are likely to be very high.
-
-\chapter{Modular Reduction}
-
-Modular reduction is process of taking the remainder of one quantity divided by another.  Expressed
-as (\ref{eqn:mod}) the modular reduction is equivalent to the remainder of $b$ divided by $c$.
-
-\begin{equation}
-a \equiv b \mbox{ (mod }c\mbox{)}
-\label{eqn:mod}
-\end{equation}
-
-Of particular interest to cryptography are reductions where $b$ is limited to the range $0 \le b < c^2$ since particularly
-fast reduction algorithms can be written for the limited range.
-
-Note that one of the four optimized reduction algorithms are automatically chosen in the modular exponentiation
-algorithm mp\_exptmod when an appropriate modulus is detected.
-
-\section{Straight Division}
-In order to effect an arbitrary modular reduction the following algorithm is provided.
-
-\index{mp\_mod}
-\begin{alltt}
-int mp_mod(mp_int *a, mp_int *b, mp_int *c);
-\end{alltt}
-
-This reduces $a$ modulo $b$ and stores the result in $c$.  The sign of $c$ shall agree with the sign
-of $b$.  This algorithm accepts an input $a$ of any range and is not limited by $0 \le a < b^2$.
-
-\section{Barrett Reduction}
-
-Barrett reduction is a generic optimized reduction algorithm that requires pre--computation to achieve
-a decent speedup over straight division.  First a $\mu$ value must be precomputed with the following function.
-
-\index{mp\_reduce\_setup}
-\begin{alltt}
-int mp_reduce_setup(mp_int *a, mp_int *b);
-\end{alltt}
-
-Given a modulus in $b$ this produces the required $\mu$ value in $a$.  For any given modulus this only has to
-be computed once.  Modular reduction can now be performed with the following.
-
-\index{mp\_reduce}
-\begin{alltt}
-int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
-\end{alltt}
-
-This will reduce $a$ in place modulo $b$ with the precomputed $\mu$ value in $c$.  $a$ must be in the range
-$0 \le a < b^2$.
-
-\begin{alltt}
-int main(void)
-\{
-   mp_int   a, b, c, mu;
-   int      result;
-
-   /* initialize a,b to desired values, mp_init mu,
-    * c and set c to 1...we want to compute a^3 mod b
-    */
-
-   /* get mu value */
-   if ((result = mp_reduce_setup(&mu, b)) != MP_OKAY) \{
-      printf("Error getting mu.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* square a to get c = a^2 */
-   if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{
-      printf("Error squaring.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* now reduce `c' modulo b */
-   if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{
-      printf("Error reducing.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* multiply a to get c = a^3 */
-   if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{
-      printf("Error reducing.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* now reduce `c' modulo b  */
-   if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{
-      printf("Error reducing.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* c now equals a^3 mod b */
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt}
-
-This program will calculate $a^3 \mbox{ mod }b$ if all the functions succeed.
-
-\section{Montgomery Reduction}
-
-Montgomery is a specialized reduction algorithm for any odd moduli.  Like Barrett reduction a pre--computation
-step is required.  This is accomplished with the following.
-
-\index{mp\_montgomery\_setup}
-\begin{alltt}
-int mp_montgomery_setup(mp_int *a, mp_digit *mp);
-\end{alltt}
-
-For the given odd moduli $a$ the precomputation value is placed in $mp$.  The reduction is computed with the
-following.
-
-\index{mp\_montgomery\_reduce}
-\begin{alltt}
-int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
-\end{alltt}
-This reduces $a$ in place modulo $m$ with the pre--computed value $mp$.   $a$ must be in the range
-$0 \le a < b^2$.
-
-Montgomery reduction is faster than Barrett reduction for moduli smaller than the ``comba'' limit.  With the default
-setup for instance, the limit is $127$ digits ($3556$--bits).   Note that this function is not limited to
-$127$ digits just that it falls back to a baseline algorithm after that point.
-
-An important observation is that this reduction does not return $a \mbox{ mod }m$ but $aR^{-1} \mbox{ mod }m$
-where $R = \beta^n$, $n$ is the n number of digits in $m$ and $\beta$ is radix used (default is $2^{28}$).
-
-To quickly calculate $R$ the following function was provided.
-
-\index{mp\_montgomery\_calc\_normalization}
-\begin{alltt}
-int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
-\end{alltt}
-Which calculates $a = R$ for the odd moduli $b$ without using multiplication or division.
-
-The normal modus operandi for Montgomery reductions is to normalize the integers before entering the system.  For
-example, to calculate $a^3 \mbox { mod }b$ using Montgomery reduction the value of $a$ can be normalized by
-multiplying it by $R$.  Consider the following code snippet.
-
-\begin{alltt}
-int main(void)
-\{
-   mp_int   a, b, c, R;
-   mp_digit mp;
-   int      result;
-
-   /* initialize a,b to desired values,
-    * mp_init R, c and set c to 1....
-    */
-
-   /* get normalization */
-   if ((result = mp_montgomery_calc_normalization(&R, b)) != MP_OKAY) \{
-      printf("Error getting norm.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* get mp value */
-   if ((result = mp_montgomery_setup(&c, &mp)) != MP_OKAY) \{
-      printf("Error setting up montgomery.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* normalize `a' so now a is equal to aR */
-   if ((result = mp_mulmod(&a, &R, &b, &a)) != MP_OKAY) \{
-      printf("Error computing aR.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* square a to get c = a^2R^2 */
-   if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{
-      printf("Error squaring.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* now reduce `c' back down to c = a^2R^2 * R^-1 == a^2R */
-   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{
-      printf("Error reducing.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* multiply a to get c = a^3R^2 */
-   if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{
-      printf("Error reducing.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* now reduce `c' back down to c = a^3R^2 * R^-1 == a^3R */
-   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{
-      printf("Error reducing.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* now reduce (again) `c' back down to c = a^3R * R^-1 == a^3 */
-   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{
-      printf("Error reducing.  \%s",
-             mp_error_to_string(result));
-      return EXIT_FAILURE;
-   \}
-
-   /* c now equals a^3 mod b */
-
-   return EXIT_SUCCESS;
-\}
-\end{alltt}
-
-This particular example does not look too efficient but it demonstrates the point of the algorithm.  By
-normalizing the inputs the reduced results are always of the form $aR$ for some variable $a$.  This allows
-a single final reduction to correct for the normalization and the fast reduction used within the algorithm.
-
-For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}.
-
-\section{Restricted Dimminished Radix}
-
-``Dimminished Radix'' reduction refers to reduction with respect to moduli that are ameniable to simple
-digit shifting and small multiplications.  In this case the ``restricted'' variant refers to moduli of the
-form $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$).
-
-As in the case of Montgomery reduction there is a pre--computation phase required for a given modulus.
-
-\index{mp\_dr\_setup}
-\begin{alltt}
-void mp_dr_setup(mp_int *a, mp_digit *d);
-\end{alltt}
-
-This computes the value required for the modulus $a$ and stores it in $d$.  This function cannot fail
-and does not return any error codes.  After the pre--computation a reduction can be performed with the
-following.
-
-\index{mp\_dr\_reduce}
-\begin{alltt}
-int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
-\end{alltt}
-
-This reduces $a$ in place modulo $b$ with the pre--computed value $mp$.  $b$ must be of a restricted
-dimminished radix form and $a$ must be in the range $0 \le a < b^2$.  Dimminished radix reductions are
-much faster than both Barrett and Montgomery reductions as they have a much lower asymtotic running time.
-
-Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA or
-BBS cryptographic purposes.  This reduction algorithm is useful for Diffie-Hellman and ECC where fixed
-primes are acceptable.
-
-Note that unlike Montgomery reduction there is no normalization process.  The result of this function is
-equal to the correct residue.
-
-\section{Unrestricted Dimminshed Radix}
-
-Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the
-form $2^k - p$ for $0 < p < \beta$.  In this sense the unrestricted reductions are more flexible as they
-can be applied to a wider range of numbers.
-
-\index{mp\_reduce\_2k\_setup}
-\begin{alltt}
-int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
-\end{alltt}
-
-This will compute the required $d$ value for the given moduli $a$.
-
-\index{mp\_reduce\_2k}
-\begin{alltt}
-int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
-\end{alltt}
-
-This will reduce $a$ in place modulo $n$ with the pre--computed value $d$.  From my experience this routine is
-slower than mp\_dr\_reduce but faster for most moduli sizes than the Montgomery reduction.
-
-\chapter{Exponentiation}
-\section{Single Digit Exponentiation}
-\index{mp\_expt\_d\_ex}
-\begin{alltt}
-int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast)
-\end{alltt}
-This function computes $c = a^b$.
-
-With parameter \textit{fast} set to $0$ the old version of the algorithm is used,
-when \textit{fast} is $1$, a faster but not statically timed version of the algorithm is used.
-
-The old version uses a simple binary left-to-right algorithm.
-It is faster than repeated multiplications by $a$ for all values of $b$ greater than three.
-
-The new version uses a binary right-to-left algorithm.
-
-The difference between the old and the new version is that the old version always
-executes $DIGIT\_BIT$ iterations. The new algorithm executes only $n$ iterations
-where $n$ is equal to the position of the highest bit that is set in $b$.
-
-\index{mp\_expt\_d}
-\begin{alltt}
-int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
-\end{alltt}
-mp\_expt\_d(a, b, c) is a wrapper function to mp\_expt\_d\_ex(a, b, c, 0).
-
-\section{Modular Exponentiation}
-\index{mp\_exptmod}
-\begin{alltt}
-int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
-\end{alltt}
-This computes $Y \equiv G^X \mbox{ (mod }P\mbox{)}$ using a variable width sliding window algorithm.  This function
-will automatically detect the fastest modular reduction technique to use during the operation.  For negative values of
-$X$ the operation is performed as $Y \equiv (G^{-1} \mbox{ mod }P)^{\vert X \vert} \mbox{ (mod }P\mbox{)}$ provided that
-$gcd(G, P) = 1$.
-
-This function is actually a shell around the two internal exponentiation functions.  This routine will automatically
-detect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix based exponentiation can be used.  Generally
-moduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations.  Followed by Montgomery
-and the other two algorithms.
-
-\section{Root Finding}
-\index{mp\_n\_root}
-\begin{alltt}
-int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
-\end{alltt}
-This computes $c = a^{1/b}$ such that $c^b \le a$ and $(c+1)^b > a$.  The implementation of this function is not
-ideal for values of $b$ greater than three.  It will work but become very slow.  So unless you are working with very small
-numbers (less than 1000 bits) I'd avoid $b > 3$ situations.  Will return a positive root only for even roots and return
-a root with the sign of the input for odd roots.  For example, performing $4^{1/2}$ will return $2$ whereas $(-8)^{1/3}$
-will return $-2$.
-
-This algorithm uses the ``Newton Approximation'' method and will converge on the correct root fairly quickly.  Since
-the algorithm requires raising $a$ to the power of $b$ it is not ideal to attempt to find roots for large
-values of $b$.  If particularly large roots are required then a factor method could be used instead.  For example,
-$a^{1/16}$ is equivalent to $\left (a^{1/4} \right)^{1/4}$ or simply
-$\left ( \left ( \left ( a^{1/2} \right )^{1/2} \right )^{1/2} \right )^{1/2}$
-
-\chapter{Prime Numbers}
-\section{Trial Division}
-\index{mp\_prime\_is\_divisible}
-\begin{alltt}
-int mp_prime_is_divisible (mp_int * a, int *result)
-\end{alltt}
-This will attempt to evenly divide $a$ by a list of primes\footnote{Default is the first 256 primes.} and store the
-outcome in ``result''.  That is if $result = 0$ then $a$ is not divisible by the primes, otherwise it is.  Note that
-if the function does not return \textbf{MP\_OKAY} the value in ``result'' should be considered undefined\footnote{Currently
-the default is to set it to zero first.}.
-
-\section{Fermat Test}
-\index{mp\_prime\_fermat}
-\begin{alltt}
-int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
-\end{alltt}
-Performs a Fermat primality test to the base $b$.  That is it computes $b^a \mbox{ mod }a$ and tests whether the value is
-equal to $b$ or not.  If the values are equal then $a$ is probably prime and $result$ is set to one.  Otherwise $result$
-is set to zero.
-
-\section{Miller-Rabin Test}
-\index{mp\_prime\_miller\_rabin}
-\begin{alltt}
-int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
-\end{alltt}
-Performs a Miller-Rabin test to the base $b$ of $a$.  This test is much stronger than the Fermat test and is very hard to
-fool (besides with Carmichael numbers).  If $a$ passes the test (therefore is probably prime) $result$ is set to one.
-Otherwise $result$ is set to zero.
-
-Note that is suggested that you use the Miller-Rabin test instead of the Fermat test since all of the failures of
-Miller-Rabin are a subset of the failures of the Fermat test.
-
-\subsection{Required Number of Tests}
-Generally to ensure a number is very likely to be prime you have to perform the Miller-Rabin with at least a half-dozen
-or so unique bases.  However, it has been proven that the probability of failure goes down as the size of the input goes up.
-This is why a simple function has been provided to help out.
-
-\index{mp\_prime\_rabin\_miller\_trials}
-\begin{alltt}
-int mp_prime_rabin_miller_trials(int size)
-\end{alltt}
-This returns the number of trials required for a $2^{-96}$ (or lower) probability of failure for a given ``size'' expressed
-in bits.  This comes in handy specially since larger numbers are slower to test.  For example, a 512-bit number would
-require ten tests whereas a 1024-bit number would only require four tests.
-
-You should always still perform a trial division before a Miller-Rabin test though.
-
-\section{Primality Testing}
-\index{mp\_prime\_is\_prime}
-\begin{alltt}
-int mp_prime_is_prime (mp_int * a, int t, int *result)
-\end{alltt}
-This will perform a trial division followed by $t$ rounds of Miller-Rabin tests on $a$ and store the result in $result$.
-If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero.  Note that $t$ is bounded by
-$1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$).
-
-\section{Next Prime}
-\index{mp\_prime\_next\_prime}
-\begin{alltt}
-int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
-\end{alltt}
-This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests.  Set $bbs\_style$ to one if you
-want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime.
-
-\section{Random Primes}
-\index{mp\_prime\_random}
-\begin{alltt}
-int mp_prime_random(mp_int *a, int t, int size, int bbs,
-                    ltm_prime_callback cb, void *dat)
-\end{alltt}
-This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass
-$t$ rounds of tests.  The ``ltm\_prime\_callback'' is a typedef for
-
-\begin{alltt}
-typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
-\end{alltt}
-
-Which is a function that must read $len$ bytes (and return the amount stored) into $dst$.  The $dat$ variable is simply
-copied from the original input.  It can be used to pass RNG context data to the callback.  The function
-mp\_prime\_random() is more suitable for generating primes which must be secret (as in the case of RSA) since there
-is no skew on the least significant bits.
-
-\textit{Note:}  As of v0.30 of the LibTomMath library this function has been deprecated.  It is still available
-but users are encouraged to use the new mp\_prime\_random\_ex() function instead.
-
-\subsection{Extended Generation}
-\index{mp\_prime\_random\_ex}
-\begin{alltt}
-int mp_prime_random_ex(mp_int *a,    int t,
-                       int     size, int flags,
-                       ltm_prime_callback cb, void *dat);
-\end{alltt}
-This will generate a prime in $a$ using $t$ tests of the primality testing algorithms.  The variable $size$
-specifies the bit length of the prime desired.  The variable $flags$ specifies one of several options available
-(see fig. \ref{fig:primeopts}) which can be OR'ed together.  The callback parameters are used as in
-mp\_prime\_random().
-
-\begin{figure}[here]
-\begin{center}
-\begin{small}
-\begin{tabular}{|r|l|}
-\hline \textbf{Flag}         & \textbf{Meaning} \\
-\hline LTM\_PRIME\_BBS       & Make the prime congruent to $3$ modulo $4$ \\
-\hline LTM\_PRIME\_SAFE      & Make a prime $p$ such that $(p - 1)/2$ is also prime. \\
-                             & This option implies LTM\_PRIME\_BBS as well. \\
-\hline LTM\_PRIME\_2MSB\_OFF & Makes sure that the bit adjacent to the most significant bit \\
-                             & Is forced to zero.  \\
-\hline LTM\_PRIME\_2MSB\_ON  & Makes sure that the bit adjacent to the most significant bit \\
-                             & Is forced to one. \\
-\hline
-\end{tabular}
-\end{small}
-\end{center}
-\caption{Primality Generation Options}
-\label{fig:primeopts}
-\end{figure}
-
-\chapter{Input and Output}
-\section{ASCII Conversions}
-\subsection{To ASCII}
-\index{mp\_toradix}
-\begin{alltt}
-int mp_toradix (mp_int * a, char *str, int radix);
-\end{alltt}
-This still store $a$ in ``str'' as a base-``radix'' string of ASCII chars.  This function appends a NUL character
-to terminate the string.  Valid values of ``radix'' line in the range $[2, 64]$.  To determine the size (exact) required
-by the conversion before storing any data use the following function.
-
-\index{mp\_radix\_size}
-\begin{alltt}
-int mp_radix_size (mp_int * a, int radix, int *size)
-\end{alltt}
-This stores in ``size'' the number of characters (including space for the NUL terminator) required.  Upon error this
-function returns an error code and ``size'' will be zero.
-
-\subsection{From ASCII}
-\index{mp\_read\_radix}
-\begin{alltt}
-int mp_read_radix (mp_int * a, char *str, int radix);
-\end{alltt}
-This will read the base-``radix'' NUL terminated string from ``str'' into $a$.  It will stop reading when it reads a
-character it does not recognize (which happens to include th NUL char... imagine that...).  A single leading $-$ sign
-can be used to denote a negative number.
-
-\section{Binary Conversions}
-
-Converting an mp\_int to and from binary is another keen idea.
-
-\index{mp\_unsigned\_bin\_size}
-\begin{alltt}
-int mp_unsigned_bin_size(mp_int *a);
-\end{alltt}
-
-This will return the number of bytes (octets) required to store the unsigned copy of the integer $a$.
-
-\index{mp\_to\_unsigned\_bin}
-\begin{alltt}
-int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
-\end{alltt}
-This will store $a$ into the buffer $b$ in big--endian format.  Fortunately this is exactly what DER (or is it ASN?)
-requires.  It does not store the sign of the integer.
-
-\index{mp\_read\_unsigned\_bin}
-\begin{alltt}
-int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c);
-\end{alltt}
-This will read in an unsigned big--endian array of bytes (octets) from $b$ of length $c$ into $a$.  The resulting
-integer $a$ will always be positive.
-
-For those who acknowledge the existence of negative numbers (heretic!) there are ``signed'' versions of the
-previous functions.
-
-\begin{alltt}
-int mp_signed_bin_size(mp_int *a);
-int mp_read_signed_bin(mp_int *a, unsigned char *b, int c);
-int mp_to_signed_bin(mp_int *a, unsigned char *b);
-\end{alltt}
-They operate essentially the same as the unsigned copies except they prefix the data with zero or non--zero
-byte depending on the sign.  If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefix
-is non--zero.
-
-\chapter{Algebraic Functions}
-\section{Extended Euclidean Algorithm}
-\index{mp\_exteuclid}
-\begin{alltt}
-int mp_exteuclid(mp_int *a, mp_int *b,
-                 mp_int *U1, mp_int *U2, mp_int *U3);
-\end{alltt}
-
-This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that the following equation holds.
-
-\begin{equation}
-a \cdot U1 + b \cdot U2 = U3
-\end{equation}
-
-Any of the U1/U2/U3 paramters can be set to \textbf{NULL} if they are not desired.
-
-\section{Greatest Common Divisor}
-\index{mp\_gcd}
-\begin{alltt}
-int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
-\end{alltt}
-This will compute the greatest common divisor of $a$ and $b$ and store it in $c$.
-
-\section{Least Common Multiple}
-\index{mp\_lcm}
-\begin{alltt}
-int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
-\end{alltt}
-This will compute the least common multiple of $a$ and $b$ and store it in $c$.
-
-\section{Jacobi Symbol}
-\index{mp\_jacobi}
-\begin{alltt}
-int mp_jacobi (mp_int * a, mp_int * p, int *c)
-\end{alltt}
-This will compute the Jacobi symbol for $a$ with respect to $p$.  If $p$ is prime this essentially computes the Legendre
-symbol.  The result is stored in $c$ and can take on one of three values $\lbrace -1, 0, 1 \rbrace$.  If $p$ is prime
-then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$.  The result will be $0$ if $a$ divides $p$
-and the result will be $1$ if $a$ is a quadratic residue modulo $p$.
-
-\section{Modular square root}
-\index{mp\_sqrtmod\_prime}
-\begin{alltt}
-int mp_sqrtmod_prime(mp_int *n, mp_int *p, mp_int *r)
-\end{alltt}
-
-This will solve the modular equatioon $r^2 = n \mod p$ where $p$ is a prime number greater than 2 (odd prime).
-The result is returned in the third argument $r$, the function returns \textbf{MP\_OKAY} on success,
-other return values indicate failure.
-
-The implementation is split for two different cases:
-
-1. if $p \mod 4 == 3$ we apply \href{http://cacr.uwaterloo.ca/hac/}{Handbook of Applied Cryptography algorithm 3.36} and compute $r$ directly as
-$r = n^{(p+1)/4} \mod p$
-
-2. otherwise we use \href{https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm}{Tonelli-Shanks algorithm}
-
-The function does not check the primality of parameter $p$ thus it is up to the caller to assure that this parameter
-is a prime number. When $p$ is a composite the function behaviour is undefined, it may even return a false-positive
-\textbf{MP\_OKAY}.
-
-\section{Modular Inverse}
-\index{mp\_invmod}
-\begin{alltt}
-int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
-\end{alltt}
-Computes the multiplicative inverse of $a$ modulo $b$ and stores the result in $c$ such that $ac \equiv 1 \mbox{ (mod }b\mbox{)}$.
-
-\section{Single Digit Functions}
-
-For those using small numbers (\textit{snicker snicker}) there are several ``helper'' functions
-
-\index{mp\_add\_d} \index{mp\_sub\_d} \index{mp\_mul\_d} \index{mp\_div\_d} \index{mp\_mod\_d}
-\begin{alltt}
-int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
-int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
-int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
-int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
-int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
-\end{alltt}
-
-These work like the full mp\_int capable variants except the second parameter $b$ is a mp\_digit.  These
-functions fairly handy if you have to work with relatively small numbers since you will not have to allocate
-an entire mp\_int to store a number like $1$ or $2$.
-
-\input{bn.ind}
-
-\end{document}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_cutoffs.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,14 @@
+#include "tommath_private.h"
+#ifdef BN_CUTOFFS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+#ifndef MP_FIXED_CUTOFFS
+#include "tommath_cutoffs.h"
+int KARATSUBA_MUL_CUTOFF = MP_DEFAULT_KARATSUBA_MUL_CUTOFF,
+    KARATSUBA_SQR_CUTOFF = MP_DEFAULT_KARATSUBA_SQR_CUTOFF,
+    TOOM_MUL_CUTOFF = MP_DEFAULT_TOOM_MUL_CUTOFF,
+    TOOM_SQR_CUTOFF = MP_DEFAULT_TOOM_SQR_CUTOFF;
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_deprecated.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,321 @@
+#include "tommath_private.h"
+#ifdef BN_DEPRECATED_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+#ifdef BN_MP_GET_BIT_C
+int mp_get_bit(const mp_int *a, int b)
+{
+   if (b < 0) {
+      return MP_VAL;
+   }
+   return (s_mp_get_bit(a, (unsigned int)b) == MP_YES) ? MP_YES : MP_NO;
+}
+#endif
+#ifdef BN_MP_JACOBI_C
+mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c)
+{
+   if (a->sign == MP_NEG) {
+      return MP_VAL;
+   }
+   if (mp_cmp_d(n, 0uL) != MP_GT) {
+      return MP_VAL;
+   }
+   return mp_kronecker(a, n, c);
+}
+#endif
+#ifdef BN_MP_PRIME_RANDOM_EX_C
+mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat)
+{
+   return s_mp_prime_random_ex(a, t, size, flags, cb, dat);
+}
+#endif
+#ifdef BN_MP_RAND_DIGIT_C
+mp_err mp_rand_digit(mp_digit *r)
+{
+   mp_err err = s_mp_rand_source(r, sizeof(mp_digit));
+   *r &= MP_MASK;
+   return err;
+}
+#endif
+#ifdef BN_FAST_MP_INVMOD_C
+mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return s_mp_invmod_fast(a, b, c);
+}
+#endif
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
+{
+   return s_mp_montgomery_reduce_fast(x, n, rho);
+}
+#endif
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
+{
+   return s_mp_mul_digs_fast(a, b, c, digs);
+}
+#endif
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
+{
+   return s_mp_mul_high_digs_fast(a, b, c, digs);
+}
+#endif
+#ifdef BN_FAST_S_MP_SQR_C
+mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b)
+{
+   return s_mp_sqr_fast(a, b);
+}
+#endif
+#ifdef BN_MP_BALANCE_MUL_C
+mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return s_mp_balance_mul(a, b, c);
+}
+#endif
+#ifdef BN_MP_EXPTMOD_FAST_C
+mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
+{
+   return s_mp_exptmod_fast(G, X, P, Y, redmode);
+}
+#endif
+#ifdef BN_MP_INVMOD_SLOW_C
+mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return s_mp_invmod_slow(a, b, c);
+}
+#endif
+#ifdef BN_MP_KARATSUBA_MUL_C
+mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return s_mp_karatsuba_mul(a, b, c);
+}
+#endif
+#ifdef BN_MP_KARATSUBA_SQR_C
+mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b)
+{
+   return s_mp_karatsuba_sqr(a, b);
+}
+#endif
+#ifdef BN_MP_TOOM_MUL_C
+mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return s_mp_toom_mul(a, b, c);
+}
+#endif
+#ifdef BN_MP_TOOM_SQR_C
+mp_err mp_toom_sqr(const mp_int *a, mp_int *b)
+{
+   return s_mp_toom_sqr(a, b);
+}
+#endif
+#ifdef S_MP_REVERSE_C
+void bn_reverse(unsigned char *s, int len)
+{
+   if (len > 0) {
+      s_mp_reverse(s, (size_t)len);
+   }
+}
+#endif
+#ifdef BN_MP_TC_AND_C
+mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return mp_and(a, b, c);
+}
+#endif
+#ifdef BN_MP_TC_OR_C
+mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return mp_or(a, b, c);
+}
+#endif
+#ifdef BN_MP_TC_XOR_C
+mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
+{
+   return mp_xor(a, b, c);
+}
+#endif
+#ifdef BN_MP_TC_DIV_2D_C
+mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c)
+{
+   return mp_signed_rsh(a, b, c);
+}
+#endif
+#ifdef BN_MP_INIT_SET_INT_C
+mp_err mp_init_set_int(mp_int *a, unsigned long b)
+{
+   return mp_init_u32(a, (uint32_t)b);
+}
+#endif
+#ifdef BN_MP_SET_INT_C
+mp_err mp_set_int(mp_int *a, unsigned long b)
+{
+   mp_set_u32(a, (uint32_t)b);
+   return MP_OKAY;
+}
+#endif
+#ifdef BN_MP_SET_LONG_C
+mp_err mp_set_long(mp_int *a, unsigned long b)
+{
+   mp_set_u64(a, b);
+   return MP_OKAY;
+}
+#endif
+#ifdef BN_MP_SET_LONG_LONG_C
+mp_err mp_set_long_long(mp_int *a, unsigned long long b)
+{
+   mp_set_u64(a, b);
+   return MP_OKAY;
+}
+#endif
+#ifdef BN_MP_GET_INT_C
+unsigned long mp_get_int(const mp_int *a)
+{
+   return (unsigned long)mp_get_mag_u32(a);
+}
+#endif
+#ifdef BN_MP_GET_LONG_C
+unsigned long mp_get_long(const mp_int *a)
+{
+   return (unsigned long)mp_get_mag_ul(a);
+}
+#endif
+#ifdef BN_MP_GET_LONG_LONG_C
+unsigned long long mp_get_long_long(const mp_int *a)
+{
+   return mp_get_mag_ull(a);
+}
+#endif
+#ifdef BN_MP_PRIME_IS_DIVISIBLE_C
+mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result)
+{
+   return s_mp_prime_is_divisible(a, result);
+}
+#endif
+#ifdef BN_MP_EXPT_D_EX_C
+mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
+{
+   (void)fast;
+   if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
+      return MP_VAL;
+   }
+   return mp_expt_u32(a, (uint32_t)b, c);
+}
+#endif
+#ifdef BN_MP_EXPT_D_C
+mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
+{
+   if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
+      return MP_VAL;
+   }
+   return mp_expt_u32(a, (uint32_t)b, c);
+}
+#endif
+#ifdef BN_MP_N_ROOT_EX_C
+mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
+{
+   (void)fast;
+   if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
+      return MP_VAL;
+   }
+   return mp_root_u32(a, (uint32_t)b, c);
+}
+#endif
+#ifdef BN_MP_N_ROOT_C
+mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c)
+{
+   if (b > MP_MIN(MP_DIGIT_MAX, UINT32_MAX)) {
+      return MP_VAL;
+   }
+   return mp_root_u32(a, (uint32_t)b, c);
+}
+#endif
+#ifdef BN_MP_UNSIGNED_BIN_SIZE_C
+int mp_unsigned_bin_size(const mp_int *a)
+{
+   return (int)mp_ubin_size(a);
+}
+#endif
+#ifdef BN_MP_READ_UNSIGNED_BIN_C
+mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c)
+{
+   return mp_from_ubin(a, b, (size_t) c);
+}
+#endif
+#ifdef BN_MP_TO_UNSIGNED_BIN_C
+mp_err mp_to_unsigned_bin(const mp_int *a, unsigned char *b)
+{
+   return mp_to_ubin(a, b, SIZE_MAX, NULL);
+}
+#endif
+#ifdef BN_MP_TO_UNSIGNED_BIN_N_C
+mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen)
+{
+   size_t n = mp_ubin_size(a);
+   if (*outlen < (unsigned long)n) {
+      return MP_VAL;
+   }
+   *outlen = (unsigned long)n;
+   return mp_to_ubin(a, b, n, NULL);
+}
+#endif
+#ifdef BN_MP_SIGNED_BIN_SIZE_C
+int mp_signed_bin_size(const mp_int *a)
+{
+   return (int)mp_sbin_size(a);
+}
+#endif
+#ifdef BN_MP_READ_SIGNED_BIN_C
+mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c)
+{
+   return mp_from_sbin(a, b, (size_t) c);
+}
+#endif
+#ifdef BN_MP_TO_SIGNED_BIN_C
+mp_err mp_to_signed_bin(const mp_int *a, unsigned char *b)
+{
+   return mp_to_sbin(a, b, SIZE_MAX, NULL);
+}
+#endif
+#ifdef BN_MP_TO_SIGNED_BIN_N_C
+mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen)
+{
+   size_t n = mp_sbin_size(a);
+   if (*outlen < (unsigned long)n) {
+      return MP_VAL;
+   }
+   *outlen = (unsigned long)n;
+   return mp_to_sbin(a, b, n, NULL);
+}
+#endif
+#ifdef BN_MP_TORADIX_N_C
+mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen)
+{
+   if (maxlen < 0) {
+      return MP_VAL;
+   }
+   return mp_to_radix(a, str, (size_t)maxlen, NULL, radix);
+}
+#endif
+#ifdef BN_MP_TORADIX_C
+mp_err mp_toradix(const mp_int *a, char *str, int radix)
+{
+   return mp_to_radix(a, str, SIZE_MAX, NULL, radix);
+}
+#endif
+#ifdef BN_MP_IMPORT_C
+mp_err mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails,
+                 const void *op)
+{
+   return mp_unpack(rop, count, order, size, endian, nails, op);
+}
+#endif
+#ifdef BN_MP_EXPORT_C
+mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
+                 int endian, size_t nails, const mp_int *op)
+{
+   return mp_pack(rop, SIZE_MAX, countp, order, size, endian, nails, op);
+}
+#endif
+#endif
--- a/libtommath/bn_error.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_ERROR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-static const struct {
-     int code;
-     const char *msg;
-} msgs[] = {
-     { MP_OKAY, "Successful" },
-     { MP_MEM,  "Out of heap" },
-     { MP_VAL,  "Value out of range" }
-};
-
-/* return a char * string for a given code */
-const char *mp_error_to_string(int code)
-{
-   int x;
-
-   /* scan the lookup table for the given message */
-   for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
-       if (msgs[x].code == code) {
-          return msgs[x].msg;
-       }
-   }
-
-   /* generic reply for invalid code */
-   return "Invalid error code";
-}
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_fast_mp_invmod.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_FAST_MP_INVMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* computes the modular inverse via binary extended euclidean algorithm, 
- * that is c = 1/a mod b 
- *
- * Based on slow invmod except this is optimized for the case where b is 
- * odd as per HAC Note 14.64 on pp. 610
- */
-int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
-{
-  mp_int  x, y, u, v, B, D;
-  int     res, neg;
-
-  /* 2. [modified] b must be odd   */
-  if (mp_iseven (b) == MP_YES) {
-    return MP_VAL;
-  }
-
-  /* init all our temps */
-  if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
-     return res;
-  }
-
-  /* x == modulus, y == value to invert */
-  if ((res = mp_copy (b, &x)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-
-  /* we need y = |a| */
-  if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-
-  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
-  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  mp_set (&D, 1);
-
-top:
-  /* 4.  while u is even do */
-  while (mp_iseven (&u) == MP_YES) {
-    /* 4.1 u = u/2 */
-    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 4.2 if B is odd then */
-    if (mp_isodd (&B) == MP_YES) {
-      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
-        goto LBL_ERR;
-      }
-    }
-    /* B = B/2 */
-    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 5.  while v is even do */
-  while (mp_iseven (&v) == MP_YES) {
-    /* 5.1 v = v/2 */
-    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 5.2 if D is odd then */
-    if (mp_isodd (&D) == MP_YES) {
-      /* D = (D-x)/2 */
-      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
-        goto LBL_ERR;
-      }
-    }
-    /* D = D/2 */
-    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 6.  if u >= v then */
-  if (mp_cmp (&u, &v) != MP_LT) {
-    /* u = u - v, B = B - D */
-    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  } else {
-    /* v - v - u, D = D - B */
-    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* if not zero goto step 4 */
-  if (mp_iszero (&u) == MP_NO) {
-    goto top;
-  }
-
-  /* now a = C, b = D, gcd == g*v */
-
-  /* if v != 1 then there is no inverse */
-  if (mp_cmp_d (&v, 1) != MP_EQ) {
-    res = MP_VAL;
-    goto LBL_ERR;
-  }
-
-  /* b is now the inverse */
-  neg = a->sign;
-  while (D.sign == MP_NEG) {
-    if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-  mp_exch (&D, c);
-  c->sign = neg;
-  res = MP_OKAY;
-
-LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
-  return res;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_fast_mp_montgomery_reduce.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* computes xR**-1 == x (mod N) via Montgomery Reduction
- *
- * This is an optimized implementation of montgomery_reduce
- * which uses the comba method to quickly calculate the columns of the
- * reduction.
- *
- * Based on Algorithm 14.32 on pp.601 of HAC.
-*/
-int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
-{
-  int     ix, res, olduse;
-  mp_word W[MP_WARRAY];
-
-  /* get old used count */
-  olduse = x->used;
-
-  /* grow a as required */
-  if (x->alloc < (n->used + 1)) {
-    if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* first we have to get the digits of the input into
-   * an array of double precision words W[...]
-   */
-  {
-    mp_word *_W;
-    mp_digit *tmpx;
-
-    /* alias for the W[] array */
-    _W   = W;
-
-    /* alias for the digits of  x*/
-    tmpx = x->dp;
-
-    /* copy the digits of a into W[0..a->used-1] */
-    for (ix = 0; ix < x->used; ix++) {
-      *_W++ = *tmpx++;
-    }
-
-    /* zero the high words of W[a->used..m->used*2] */
-    for (; ix < ((n->used * 2) + 1); ix++) {
-      *_W++ = 0;
-    }
-  }
-
-  /* now we proceed to zero successive digits
-   * from the least significant upwards
-   */
-  for (ix = 0; ix < n->used; ix++) {
-    /* mu = ai * m' mod b
-     *
-     * We avoid a double precision multiplication (which isn't required)
-     * by casting the value down to a mp_digit.  Note this requires
-     * that W[ix-1] have  the carry cleared (see after the inner loop)
-     */
-    mp_digit mu;
-    mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
-
-    /* a = a + mu * m * b**i
-     *
-     * This is computed in place and on the fly.  The multiplication
-     * by b**i is handled by offseting which columns the results
-     * are added to.
-     *
-     * Note the comba method normally doesn't handle carries in the
-     * inner loop In this case we fix the carry from the previous
-     * column since the Montgomery reduction requires digits of the
-     * result (so far) [see above] to work.  This is
-     * handled by fixing up one carry after the inner loop.  The
-     * carry fixups are done in order so after these loops the
-     * first m->used words of W[] have the carries fixed
-     */
-    {
-      int iy;
-      mp_digit *tmpn;
-      mp_word *_W;
-
-      /* alias for the digits of the modulus */
-      tmpn = n->dp;
-
-      /* Alias for the columns set by an offset of ix */
-      _W = W + ix;
-
-      /* inner loop */
-      for (iy = 0; iy < n->used; iy++) {
-          *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
-      }
-    }
-
-    /* now fix carry for next digit, W[ix+1] */
-    W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
-  }
-
-  /* now we have to propagate the carries and
-   * shift the words downward [all those least
-   * significant digits we zeroed].
-   */
-  {
-    mp_digit *tmpx;
-    mp_word *_W, *_W1;
-
-    /* nox fix rest of carries */
-
-    /* alias for current word */
-    _W1 = W + ix;
-
-    /* alias for next word, where the carry goes */
-    _W = W + ++ix;
-
-    for (; ix <= ((n->used * 2) + 1); ix++) {
-      *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
-    }
-
-    /* copy out, A = A/b**n
-     *
-     * The result is A/b**n but instead of converting from an
-     * array of mp_word to mp_digit than calling mp_rshd
-     * we just copy them in the right order
-     */
-
-    /* alias for destination word */
-    tmpx = x->dp;
-
-    /* alias for shifted double precision result */
-    _W = W + n->used;
-
-    for (ix = 0; ix < (n->used + 1); ix++) {
-      *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
-    }
-
-    /* zero oldused digits, if the input a was larger than
-     * m->used+1 we'll have to clear the digits
-     */
-    for (; ix < olduse; ix++) {
-      *tmpx++ = 0;
-    }
-  }
-
-  /* set the max used and clamp */
-  x->used = n->used + 1;
-  mp_clamp (x);
-
-  /* if A >= m then A = A - m */
-  if (mp_cmp_mag (x, n) != MP_LT) {
-    return s_mp_sub (x, n, x);
-  }
-  return MP_OKAY;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_fast_s_mp_mul_digs.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_FAST_S_MP_MUL_DIGS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* Fast (comba) multiplier
- *
- * This is the fast column-array [comba] multiplier.  It is 
- * designed to compute the columns of the product first 
- * then handle the carries afterwards.  This has the effect 
- * of making the nested loops that compute the columns very
- * simple and schedulable on super-scalar processors.
- *
- * This has been modified to produce a variable number of 
- * digits of output so if say only a half-product is required 
- * you don't have to compute the upper half (a feature 
- * required for fast Barrett reduction).
- *
- * Based on Algorithm 14.12 on pp.595 of HAC.
- *
- */
-int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
-  int     olduse, res, pa, ix, iz;
-  mp_digit W[MP_WARRAY];
-  mp_word  _W;
-
-  /* grow the destination as required */
-  if (c->alloc < digs) {
-    if ((res = mp_grow (c, digs)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* number of output digits to produce */
-  pa = MIN(digs, a->used + b->used);
-
-  /* clear the carry */
-  _W = 0;
-  for (ix = 0; ix < pa; ix++) { 
-      int      tx, ty;
-      int      iy;
-      mp_digit *tmpx, *tmpy;
-
-      /* get offsets into the two bignums */
-      ty = MIN(b->used-1, ix);
-      tx = ix - ty;
-
-      /* setup temp aliases */
-      tmpx = a->dp + tx;
-      tmpy = b->dp + ty;
-
-      /* this is the number of times the loop will iterrate, essentially 
-         while (tx++ < a->used && ty-- >= 0) { ... }
-       */
-      iy = MIN(a->used-tx, ty+1);
-
-      /* execute loop */
-      for (iz = 0; iz < iy; ++iz) {
-         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
-
-      }
-
-      /* store term */
-      W[ix] = ((mp_digit)_W) & MP_MASK;
-
-      /* make next carry */
-      _W = _W >> ((mp_word)DIGIT_BIT);
-  }
-
-  /* setup dest */
-  olduse  = c->used;
-  c->used = pa;
-
-  {
-    mp_digit *tmpc;
-    tmpc = c->dp;
-    for (ix = 0; ix < pa; ix++) {
-      /* now extract the previous digit [below the carry] */
-      *tmpc++ = W[ix];
-    }
-
-    /* clear unused digits [that existed in the old copy of c] */
-    for (; ix < olduse; ix++) {
-      *tmpc++ = 0;
-    }
-  }
-  mp_clamp (c);
-  return MP_OKAY;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_fast_s_mp_mul_high_digs.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* this is a modified version of fast_s_mul_digs that only produces
- * output digits *above* digs.  See the comments for fast_s_mul_digs
- * to see how it works.
- *
- * This is used in the Barrett reduction since for one of the multiplications
- * only the higher digits were needed.  This essentially halves the work.
- *
- * Based on Algorithm 14.12 on pp.595 of HAC.
- */
-int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
-  int     olduse, res, pa, ix, iz;
-  mp_digit W[MP_WARRAY];
-  mp_word  _W;
-
-  /* grow the destination as required */
-  pa = a->used + b->used;
-  if (c->alloc < pa) {
-    if ((res = mp_grow (c, pa)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* number of output digits to produce */
-  pa = a->used + b->used;
-  _W = 0;
-  for (ix = digs; ix < pa; ix++) { 
-      int      tx, ty, iy;
-      mp_digit *tmpx, *tmpy;
-
-      /* get offsets into the two bignums */
-      ty = MIN(b->used-1, ix);
-      tx = ix - ty;
-
-      /* setup temp aliases */
-      tmpx = a->dp + tx;
-      tmpy = b->dp + ty;
-
-      /* this is the number of times the loop will iterrate, essentially its 
-         while (tx++ < a->used && ty-- >= 0) { ... }
-       */
-      iy = MIN(a->used-tx, ty+1);
-
-      /* execute loop */
-      for (iz = 0; iz < iy; iz++) {
-         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
-      }
-
-      /* store term */
-      W[ix] = ((mp_digit)_W) & MP_MASK;
-
-      /* make next carry */
-      _W = _W >> ((mp_word)DIGIT_BIT);
-  }
-  
-  /* setup dest */
-  olduse  = c->used;
-  c->used = pa;
-
-  {
-    mp_digit *tmpc;
-
-    tmpc = c->dp + digs;
-    for (ix = digs; ix < pa; ix++) {
-      /* now extract the previous digit [below the carry] */
-      *tmpc++ = W[ix];
-    }
-
-    /* clear unused digits [that existed in the old copy of c] */
-    for (; ix < olduse; ix++) {
-      *tmpc++ = 0;
-    }
-  }
-  mp_clamp (c);
-  return MP_OKAY;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_fast_s_mp_sqr.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_FAST_S_MP_SQR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* the jist of squaring...
- * you do like mult except the offset of the tmpx [one that 
- * starts closer to zero] can't equal the offset of tmpy.  
- * So basically you set up iy like before then you min it with
- * (ty-tx) so that it never happens.  You double all those 
- * you add in the inner loop
-
-After that loop you do the squares and add them in.
-*/
-
-int fast_s_mp_sqr (mp_int * a, mp_int * b)
-{
-  int       olduse, res, pa, ix, iz;
-  mp_digit   W[MP_WARRAY], *tmpx;
-  mp_word   W1;
-
-  /* grow the destination as required */
-  pa = a->used + a->used;
-  if (b->alloc < pa) {
-    if ((res = mp_grow (b, pa)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* number of output digits to produce */
-  W1 = 0;
-  for (ix = 0; ix < pa; ix++) { 
-      int      tx, ty, iy;
-      mp_word  _W;
-      mp_digit *tmpy;
-
-      /* clear counter */
-      _W = 0;
-
-      /* get offsets into the two bignums */
-      ty = MIN(a->used-1, ix);
-      tx = ix - ty;
-
-      /* setup temp aliases */
-      tmpx = a->dp + tx;
-      tmpy = a->dp + ty;
-
-      /* this is the number of times the loop will iterrate, essentially
-         while (tx++ < a->used && ty-- >= 0) { ... }
-       */
-      iy = MIN(a->used-tx, ty+1);
-
-      /* now for squaring tx can never equal ty 
-       * we halve the distance since they approach at a rate of 2x
-       * and we have to round because odd cases need to be executed
-       */
-      iy = MIN(iy, ((ty-tx)+1)>>1);
-
-      /* execute loop */
-      for (iz = 0; iz < iy; iz++) {
-         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
-      }
-
-      /* double the inner product and add carry */
-      _W = _W + _W + W1;
-
-      /* even columns have the square term in them */
-      if ((ix&1) == 0) {
-         _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
-      }
-
-      /* store it */
-      W[ix] = (mp_digit)(_W & MP_MASK);
-
-      /* make next carry */
-      W1 = _W >> ((mp_word)DIGIT_BIT);
-  }
-
-  /* setup dest */
-  olduse  = b->used;
-  b->used = a->used+a->used;
-
-  {
-    mp_digit *tmpb;
-    tmpb = b->dp;
-    for (ix = 0; ix < pa; ix++) {
-      *tmpb++ = W[ix] & MP_MASK;
-    }
-
-    /* clear unused digits [that existed in the old copy of c] */
-    for (; ix < olduse; ix++) {
-      *tmpb++ = 0;
-    }
-  }
-  mp_clamp (b);
-  return MP_OKAY;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_2expt.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_2expt.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,48 +1,31 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_2EXPT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-/* computes a = 2**b 
+/* computes a = 2**b
  *
  * Simple algorithm which zeroes the int, grows it then just sets one bit
  * as required.
  */
-int
-mp_2expt (mp_int * a, int b)
+mp_err mp_2expt(mp_int *a, int b)
 {
-  int     res;
+   mp_err    err;
 
-  /* zero a as per default */
-  mp_zero (a);
+   /* zero a as per default */
+   mp_zero(a);
 
-  /* grow a to accomodate the single bit */
-  if ((res = mp_grow (a, (b / DIGIT_BIT) + 1)) != MP_OKAY) {
-    return res;
-  }
+   /* grow a to accomodate the single bit */
+   if ((err = mp_grow(a, (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
+      return err;
+   }
 
-  /* set the used count of where the bit will go */
-  a->used = (b / DIGIT_BIT) + 1;
+   /* set the used count of where the bit will go */
+   a->used = (b / MP_DIGIT_BIT) + 1;
 
-  /* put the single bit in its place */
-  a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
+   /* put the single bit in its place */
+   a->dp[b / MP_DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT);
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_abs.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_abs.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,43 +1,26 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_ABS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-/* b = |a| 
+/* b = |a|
  *
  * Simple function copies the input and fixes the sign to positive
  */
-int
-mp_abs (mp_int * a, mp_int * b)
+mp_err mp_abs(const mp_int *a, mp_int *b)
 {
-  int     res;
+   mp_err     err;
 
-  /* copy a to b */
-  if (a != b) {
-     if ((res = mp_copy (a, b)) != MP_OKAY) {
-       return res;
-     }
-  }
+   /* copy a to b */
+   if (a != b) {
+      if ((err = mp_copy(a, b)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  /* force the sign of b to positive */
-  b->sign = MP_ZPOS;
+   /* force the sign of b to positive */
+   b->sign = MP_ZPOS;
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_add.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_add.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,53 +1,38 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_ADD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* high level addition (handles signs) */
-int mp_add (mp_int * a, mp_int * b, mp_int * c)
+mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  int     sa, sb, res;
+   mp_sign sa, sb;
+   mp_err err;
 
-  /* get sign of both inputs */
-  sa = a->sign;
-  sb = b->sign;
+   /* get sign of both inputs */
+   sa = a->sign;
+   sb = b->sign;
 
-  /* handle two cases, not four */
-  if (sa == sb) {
-    /* both positive or both negative */
-    /* add their magnitudes, copy the sign */
-    c->sign = sa;
-    res = s_mp_add (a, b, c);
-  } else {
-    /* one positive, the other negative */
-    /* subtract the one with the greater magnitude from */
-    /* the one of the lesser magnitude.  The result gets */
-    /* the sign of the one with the greater magnitude. */
-    if (mp_cmp_mag (a, b) == MP_LT) {
-      c->sign = sb;
-      res = s_mp_sub (b, a, c);
-    } else {
+   /* handle two cases, not four */
+   if (sa == sb) {
+      /* both positive or both negative */
+      /* add their magnitudes, copy the sign */
       c->sign = sa;
-      res = s_mp_sub (a, b, c);
-    }
-  }
-  return res;
+      err = s_mp_add(a, b, c);
+   } else {
+      /* one positive, the other negative */
+      /* subtract the one with the greater magnitude from */
+      /* the one of the lesser magnitude.  The result gets */
+      /* the sign of the one with the greater magnitude. */
+      if (mp_cmp_mag(a, b) == MP_LT) {
+         c->sign = sb;
+         err = s_mp_sub(b, a, c);
+      } else {
+         c->sign = sa;
+         err = s_mp_sub(a, b, c);
+      }
+   }
+   return err;
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_add_d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_add_d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,112 +1,89 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_ADD_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* single digit addition */
-int
-mp_add_d (mp_int * a, mp_digit b, mp_int * c)
+mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
 {
-  int     res, ix, oldused;
-  mp_digit *tmpa, *tmpc, mu;
+   mp_err     err;
+   int ix, oldused;
+   mp_digit *tmpa, *tmpc;
 
-  /* grow c as required */
-  if (c->alloc < (a->used + 1)) {
-     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
-        return res;
-     }
-  }
+   /* grow c as required */
+   if (c->alloc < (a->used + 1)) {
+      if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  /* if a is negative and |a| >= b, call c = |a| - b */
-  if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
-     /* temporarily fix sign of a */
-     a->sign = MP_ZPOS;
+   /* if a is negative and |a| >= b, call c = |a| - b */
+   if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) {
+      mp_int a_ = *a;
+      /* temporarily fix sign of a */
+      a_.sign = MP_ZPOS;
 
-     /* c = |a| - b */
-     res = mp_sub_d(a, b, c);
+      /* c = |a| - b */
+      err = mp_sub_d(&a_, b, c);
 
-     /* fix sign  */
-     a->sign = c->sign = MP_NEG;
+      /* fix sign  */
+      c->sign = MP_NEG;
 
-     /* clamp */
-     mp_clamp(c);
+      /* clamp */
+      mp_clamp(c);
 
-     return res;
-  }
+      return err;
+   }
 
-  /* old number of used digits in c */
-  oldused = c->used;
+   /* old number of used digits in c */
+   oldused = c->used;
 
-  /* source alias */
-  tmpa    = a->dp;
+   /* source alias */
+   tmpa    = a->dp;
 
-  /* destination alias */
-  tmpc    = c->dp;
+   /* destination alias */
+   tmpc    = c->dp;
 
-  /* if a is positive */
-  if (a->sign == MP_ZPOS) {
-     /* add digit, after this we're propagating
-      * the carry.
-      */
-     *tmpc   = *tmpa++ + b;
-     mu      = *tmpc >> DIGIT_BIT;
-     *tmpc++ &= MP_MASK;
+   /* if a is positive */
+   if (a->sign == MP_ZPOS) {
+      /* add digits, mu is carry */
+      mp_digit mu = b;
+      for (ix = 0; ix < a->used; ix++) {
+         *tmpc   = *tmpa++ + mu;
+         mu      = *tmpc >> MP_DIGIT_BIT;
+         *tmpc++ &= MP_MASK;
+      }
+      /* set final carry */
+      ix++;
+      *tmpc++  = mu;
 
-     /* now handle rest of the digits */
-     for (ix = 1; ix < a->used; ix++) {
-        *tmpc   = *tmpa++ + mu;
-        mu      = *tmpc >> DIGIT_BIT;
-        *tmpc++ &= MP_MASK;
-     }
-     /* set final carry */
-     ix++;
-     *tmpc++  = mu;
+      /* setup size */
+      c->used = a->used + 1;
+   } else {
+      /* a was negative and |a| < b */
+      c->used  = 1;
 
-     /* setup size */
-     c->used = a->used + 1;
-  } else {
-     /* a was negative and |a| < b */
-     c->used  = 1;
-
-     /* the result is a single digit */
-     if (a->used == 1) {
-        *tmpc++  =  b - a->dp[0];
-     } else {
-        *tmpc++  =  b;
-     }
+      /* the result is a single digit */
+      if (a->used == 1) {
+         *tmpc++  =  b - a->dp[0];
+      } else {
+         *tmpc++  =  b;
+      }
 
-     /* setup count so the clearing of oldused
-      * can fall through correctly
-      */
-     ix       = 1;
-  }
+      /* setup count so the clearing of oldused
+       * can fall through correctly
+       */
+      ix       = 1;
+   }
 
-  /* sign always positive */
-  c->sign = MP_ZPOS;
+   /* sign always positive */
+   c->sign = MP_ZPOS;
 
-  /* now zero to oldused */
-  while (ix++ < oldused) {
-     *tmpc++ = 0;
-  }
-  mp_clamp(c);
+   /* now zero to oldused */
+   MP_ZERO_DIGITS(tmpc, oldused - ix);
+   mp_clamp(c);
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_addmod.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_addmod.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,41 +1,25 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_ADDMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* d = a + b (mod c) */
-int
-mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
 {
-  int     res;
-  mp_int  t;
+   mp_err  err;
+   mp_int  t;
+
+   if ((err = mp_init(&t)) != MP_OKAY) {
+      return err;
+   }
 
-  if ((res = mp_init (&t)) != MP_OKAY) {
-    return res;
-  }
+   if ((err = mp_add(a, b, &t)) != MP_OKAY) {
+      goto LBL_ERR;
+   }
+   err = mp_mod(&t, c, d);
 
-  if ((res = mp_add (a, b, &t)) != MP_OKAY) {
-    mp_clear (&t);
-    return res;
-  }
-  res = mp_mod (&t, c, d);
-  mp_clear (&t);
-  return res;
+LBL_ERR:
+   mp_clear(&t);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_and.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_and.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,57 +1,56 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_AND_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-/* AND two ints together */
-int
-mp_and (mp_int * a, mp_int * b, mp_int * c)
+/* two complement and */
+mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  int     res, ix, px;
-  mp_int  t, *x;
+   int used = MP_MAX(a->used, b->used) + 1, i;
+   mp_err err;
+   mp_digit ac = 1, bc = 1, cc = 1;
+   mp_sign csign = ((a->sign == MP_NEG) && (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS;
+
+   if (c->alloc < used) {
+      if ((err = mp_grow(c, used)) != MP_OKAY) {
+         return err;
+      }
+   }
+
+   for (i = 0; i < used; i++) {
+      mp_digit x, y;
 
-  if (a->used > b->used) {
-    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
-      return res;
-    }
-    px = b->used;
-    x = b;
-  } else {
-    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
-      return res;
-    }
-    px = a->used;
-    x = a;
-  }
+      /* convert to two complement if negative */
+      if (a->sign == MP_NEG) {
+         ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
+         x = ac & MP_MASK;
+         ac >>= MP_DIGIT_BIT;
+      } else {
+         x = (i >= a->used) ? 0uL : a->dp[i];
+      }
 
-  for (ix = 0; ix < px; ix++) {
-    t.dp[ix] &= x->dp[ix];
-  }
+      /* convert to two complement if negative */
+      if (b->sign == MP_NEG) {
+         bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
+         y = bc & MP_MASK;
+         bc >>= MP_DIGIT_BIT;
+      } else {
+         y = (i >= b->used) ? 0uL : b->dp[i];
+      }
+
+      c->dp[i] = x & y;
 
-  /* zero digits above the last from the smallest mp_int */
-  for (; ix < t.used; ix++) {
-    t.dp[ix] = 0;
-  }
+      /* convert to to sign-magnitude if negative */
+      if (csign == MP_NEG) {
+         cc += ~c->dp[i] & MP_MASK;
+         c->dp[i] = cc & MP_MASK;
+         cc >>= MP_DIGIT_BIT;
+      }
+   }
 
-  mp_clamp (&t);
-  mp_exch (c, &t);
-  mp_clear (&t);
-  return MP_OKAY;
+   c->used = used;
+   c->sign = csign;
+   mp_clamp(c);
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_clamp.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_clamp.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,44 +1,27 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_CLAMP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-/* trim unused digits 
+/* trim unused digits
  *
  * This is used to ensure that leading zero digits are
  * trimed and the leading "used" digit will be non-zero
  * Typically very fast.  Also fixes the sign if there
  * are no more leading digits
  */
-void
-mp_clamp (mp_int * a)
+void mp_clamp(mp_int *a)
 {
-  /* decrease used while the most significant digit is
-   * zero.
-   */
-  while ((a->used > 0) && (a->dp[a->used - 1] == 0)) {
-    --(a->used);
-  }
+   /* decrease used while the most significant digit is
+    * zero.
+    */
+   while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) {
+      --(a->used);
+   }
 
-  /* reset the sign flag if used == 0 */
-  if (a->used == 0) {
-    a->sign = MP_ZPOS;
-  }
+   /* reset the sign flag if used == 0 */
+   if (a->used == 0) {
+      a->sign = MP_ZPOS;
+   }
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_clear.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_clear.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,41 +1,20 @@
-#include <tommath_private.h>
-#include "dbhelpers.h"
+#include "tommath_private.h"
 #ifdef BN_MP_CLEAR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* clear one (frees)  */
-void
-mp_clear (mp_int * a)
+void mp_clear(mp_int *a)
 {
-  /* only do anything if a hasn't been freed previously */
-  if (a->dp != NULL) {
-    /* first zero the digits */
-	m_burn(a->dp, a->alloc * sizeof(*a->dp));
+   /* only do anything if a hasn't been freed previously */
+   if (a->dp != NULL) {
+      /* free ram */
+      MP_FREE_DIGITS(a->dp, a->alloc);
 
-    /* free ram */
-    XFREE(a->dp);
-
-    /* reset members to make debugging easier */
-    a->dp    = NULL;
-    a->alloc = a->used = 0;
-    a->sign  = MP_ZPOS;
-  }
+      /* reset members to make debugging easier */
+      a->dp    = NULL;
+      a->alloc = a->used = 0;
+      a->sign  = MP_ZPOS;
+   }
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_clear_multi.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_clear_multi.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,34 +1,19 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_CLEAR_MULTI_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
 #include <stdarg.h>
 
-void mp_clear_multi(mp_int *mp, ...) 
+void mp_clear_multi(mp_int *mp, ...)
 {
-    mp_int* next_mp = mp;
-    va_list args;
-    va_start(args, mp);
-    while (next_mp != NULL) {
-        mp_clear(next_mp);
-        next_mp = va_arg(args, mp_int*);
-    }
-    va_end(args);
+   mp_int *next_mp = mp;
+   va_list args;
+   va_start(args, mp);
+   while (next_mp != NULL) {
+      mp_clear(next_mp);
+      next_mp = va_arg(args, mp_int *);
+   }
+   va_end(args);
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_cmp.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_cmp.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,43 +1,26 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_CMP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* compare two ints (signed)*/
-int
-mp_cmp (mp_int * a, mp_int * b)
+mp_ord mp_cmp(const mp_int *a, const mp_int *b)
 {
-  /* compare based on sign */
-  if (a->sign != b->sign) {
-     if (a->sign == MP_NEG) {
-        return MP_LT;
-     } else {
-        return MP_GT;
-     }
-  }
-  
-  /* compare digits */
-  if (a->sign == MP_NEG) {
-     /* if negative compare opposite direction */
-     return mp_cmp_mag(b, a);
-  } else {
-     return mp_cmp_mag(a, b);
-  }
+   /* compare based on sign */
+   if (a->sign != b->sign) {
+      if (a->sign == MP_NEG) {
+         return MP_LT;
+      } else {
+         return MP_GT;
+      }
+   }
+
+   /* compare digits */
+   if (a->sign == MP_NEG) {
+      /* if negative compare opposite direction */
+      return mp_cmp_mag(b, a);
+   } else {
+      return mp_cmp_mag(a, b);
+   }
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_cmp_d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_cmp_d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,44 +1,28 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_CMP_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* compare a digit */
-int mp_cmp_d(mp_int * a, mp_digit b)
+mp_ord mp_cmp_d(const mp_int *a, mp_digit b)
 {
-  /* compare based on sign */
-  if (a->sign == MP_NEG) {
-    return MP_LT;
-  }
+   /* compare based on sign */
+   if (a->sign == MP_NEG) {
+      return MP_LT;
+   }
 
-  /* compare based on magnitude */
-  if (a->used > 1) {
-    return MP_GT;
-  }
+   /* compare based on magnitude */
+   if (a->used > 1) {
+      return MP_GT;
+   }
 
-  /* compare the only digit of a to b */
-  if (a->dp[0] > b) {
-    return MP_GT;
-  } else if (a->dp[0] < b) {
-    return MP_LT;
-  } else {
-    return MP_EQ;
-  }
+   /* compare the only digit of a to b */
+   if (a->dp[0] > b) {
+      return MP_GT;
+   } else if (a->dp[0] < b) {
+      return MP_LT;
+   } else {
+      return MP_EQ;
+   }
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_cmp_mag.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_cmp_mag.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,55 +1,39 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_CMP_MAG_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* compare maginitude of two ints (unsigned) */
-int mp_cmp_mag (mp_int * a, mp_int * b)
+mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b)
 {
-  int     n;
-  mp_digit *tmpa, *tmpb;
+   int     n;
+   const mp_digit *tmpa, *tmpb;
 
-  /* compare based on # of non-zero digits */
-  if (a->used > b->used) {
-    return MP_GT;
-  }
-  
-  if (a->used < b->used) {
-    return MP_LT;
-  }
+   /* compare based on # of non-zero digits */
+   if (a->used > b->used) {
+      return MP_GT;
+   }
+
+   if (a->used < b->used) {
+      return MP_LT;
+   }
 
-  /* alias for a */
-  tmpa = a->dp + (a->used - 1);
+   /* alias for a */
+   tmpa = a->dp + (a->used - 1);
 
-  /* alias for b */
-  tmpb = b->dp + (a->used - 1);
+   /* alias for b */
+   tmpb = b->dp + (a->used - 1);
 
-  /* compare based on digits  */
-  for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
-    if (*tmpa > *tmpb) {
-      return MP_GT;
-    }
+   /* compare based on digits  */
+   for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
+      if (*tmpa > *tmpb) {
+         return MP_GT;
+      }
 
-    if (*tmpa < *tmpb) {
-      return MP_LT;
-    }
-  }
-  return MP_EQ;
+      if (*tmpa < *tmpb) {
+         return MP_LT;
+      }
+   }
+   return MP_EQ;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_cnt_lsb.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_cnt_lsb.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,53 +1,37 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_CNT_LSB_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-static const int lnz[16] = { 
+static const int lnz[16] = {
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
 };
 
 /* Counts the number of lsbs which are zero before the first zero bit */
-int mp_cnt_lsb(mp_int *a)
+int mp_cnt_lsb(const mp_int *a)
 {
    int x;
    mp_digit q, qq;
 
    /* easy out */
-   if (mp_iszero(a) == MP_YES) {
+   if (MP_IS_ZERO(a)) {
       return 0;
    }
 
    /* scan lower digits until non-zero */
-   for (x = 0; (x < a->used) && (a->dp[x] == 0); x++) {}
+   for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {}
    q = a->dp[x];
-   x *= DIGIT_BIT;
+   x *= MP_DIGIT_BIT;
 
    /* now scan this digit until a 1 is found */
-   if ((q & 1) == 0) {
+   if ((q & 1u) == 0u) {
       do {
-         qq  = q & 15;
+         qq  = q & 15u;
          x  += lnz[qq];
          q >>= 4;
-      } while (qq == 0);
+      } while (qq == 0u);
    }
    return x;
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_complement.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,12 @@
+#include "tommath_private.h"
+#ifdef BN_MP_COMPLEMENT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* b = ~a */
+mp_err mp_complement(const mp_int *a, mp_int *b)
+{
+   mp_err err = mp_neg(a, b);
+   return (err == MP_OKAY) ? mp_sub_d(b, 1uL, b) : err;
+}
+#endif
--- a/libtommath/bn_mp_copy.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_copy.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,68 +1,47 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_COPY_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* copy, b = a */
-int
-mp_copy (mp_int * a, mp_int * b)
+mp_err mp_copy(const mp_int *a, mp_int *b)
 {
-  int     res, n;
-
-  /* if dst == src do nothing */
-  if (a == b) {
-    return MP_OKAY;
-  }
+   int n;
+   mp_digit *tmpa, *tmpb;
+   mp_err err;
 
-  /* grow dest */
-  if (b->alloc < a->used) {
-     if ((res = mp_grow (b, a->used)) != MP_OKAY) {
-        return res;
-     }
-  }
+   /* if dst == src do nothing */
+   if (a == b) {
+      return MP_OKAY;
+   }
 
-  /* zero b and copy the parameters over */
-  {
-    mp_digit *tmpa, *tmpb;
+   /* grow dest */
+   if (b->alloc < a->used) {
+      if ((err = mp_grow(b, a->used)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-    /* pointer aliases */
+   /* zero b and copy the parameters over */
+   /* pointer aliases */
 
-    /* source */
-    tmpa = a->dp;
+   /* source */
+   tmpa = a->dp;
 
-    /* destination */
-    tmpb = b->dp;
+   /* destination */
+   tmpb = b->dp;
 
-    /* copy all the digits */
-    for (n = 0; n < a->used; n++) {
+   /* copy all the digits */
+   for (n = 0; n < a->used; n++) {
       *tmpb++ = *tmpa++;
-    }
+   }
+
+   /* clear high digits */
+   MP_ZERO_DIGITS(tmpb, b->used - n);
 
-    /* clear high digits */
-    for (; n < b->used; n++) {
-      *tmpb++ = 0;
-    }
-  }
-
-  /* copy used count and sign */
-  b->used = a->used;
-  b->sign = a->sign;
-  return MP_OKAY;
+   /* copy used count and sign */
+   b->used = a->used;
+   b->sign = a->sign;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_count_bits.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_count_bits.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,45 +1,28 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_COUNT_BITS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* returns the number of bits in an int */
-int
-mp_count_bits (mp_int * a)
+int mp_count_bits(const mp_int *a)
 {
-  int     r;
-  mp_digit q;
+   int     r;
+   mp_digit q;
 
-  /* shortcut */
-  if (a->used == 0) {
-    return 0;
-  }
+   /* shortcut */
+   if (MP_IS_ZERO(a)) {
+      return 0;
+   }
 
-  /* get number of digits and add that */
-  r = (a->used - 1) * DIGIT_BIT;
-  
-  /* take the last digit and count the bits in it */
-  q = a->dp[a->used - 1];
-  while (q > ((mp_digit) 0)) {
-    ++r;
-    q >>= ((mp_digit) 1);
-  }
-  return r;
+   /* get number of digits and add that */
+   r = (a->used - 1) * MP_DIGIT_BIT;
+
+   /* take the last digit and count the bits in it */
+   q = a->dp[a->used - 1];
+   while (q > 0u) {
+      ++r;
+      q >>= 1u;
+   }
+   return r;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_decr.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,34 @@
+#include "tommath_private.h"
+#ifdef BN_MP_DECR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* Decrement "a" by one like "a--". Changes input! */
+mp_err mp_decr(mp_int *a)
+{
+   if (MP_IS_ZERO(a)) {
+      mp_set(a,1uL);
+      a->sign = MP_NEG;
+      return MP_OKAY;
+   } else if (a->sign == MP_NEG) {
+      mp_err err;
+      a->sign = MP_ZPOS;
+      if ((err = mp_incr(a)) != MP_OKAY) {
+         return err;
+      }
+      /* There is no -0 in LTM */
+      if (!MP_IS_ZERO(a)) {
+         a->sign = MP_NEG;
+      }
+      return MP_OKAY;
+   } else if (a->dp[0] > 1uL) {
+      a->dp[0]--;
+      if (a->dp[0] == 0u) {
+         mp_zero(a);
+      }
+      return MP_OKAY;
+   } else {
+      return mp_sub_d(a, 1uL,a);
+   }
+}
+#endif
--- a/libtommath/bn_mp_div.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_div.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,88 +1,71 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DIV_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 #ifdef BN_MP_DIV_SMALL
 
 /* slower bit-bang division... also smaller */
-int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
 {
    mp_int ta, tb, tq, q;
-   int    res, n, n2;
+   int     n, n2;
+   mp_err err;
 
-  /* is divisor zero ? */
-  if (mp_iszero (b) == MP_YES) {
-    return MP_VAL;
-  }
+   /* is divisor zero ? */
+   if (MP_IS_ZERO(b)) {
+      return MP_VAL;
+   }
 
-  /* if a < b then q=0, r = a */
-  if (mp_cmp_mag (a, b) == MP_LT) {
-    if (d != NULL) {
-      res = mp_copy (a, d);
-    } else {
-      res = MP_OKAY;
-    }
-    if (c != NULL) {
-      mp_zero (c);
-    }
-    return res;
-  }
+   /* if a < b then q=0, r = a */
+   if (mp_cmp_mag(a, b) == MP_LT) {
+      if (d != NULL) {
+         err = mp_copy(a, d);
+      } else {
+         err = MP_OKAY;
+      }
+      if (c != NULL) {
+         mp_zero(c);
+      }
+      return err;
+   }
 
-  /* init our temps */
-  if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
-     return res;
-  }
+   /* init our temps */
+   if ((err = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
+      return err;
+   }
 
 
-  mp_set(&tq, 1);
-  n = mp_count_bits(a) - mp_count_bits(b);
-  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
-      ((res = mp_abs(b, &tb)) != MP_OKAY) ||
-      ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
-      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
-      goto LBL_ERR;
-  }
+   mp_set(&tq, 1uL);
+   n = mp_count_bits(a) - mp_count_bits(b);
+   if ((err = mp_abs(a, &ta)) != MP_OKAY)                         goto LBL_ERR;
+   if ((err = mp_abs(b, &tb)) != MP_OKAY)                         goto LBL_ERR;
+   if ((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY)                 goto LBL_ERR;
+   if ((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)                 goto LBL_ERR;
 
-  while (n-- >= 0) {
-     if (mp_cmp(&tb, &ta) != MP_GT) {
-        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
-            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
-           goto LBL_ERR;
-        }
-     }
-     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
-         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
-           goto LBL_ERR;
-     }
-  }
+   while (n-- >= 0) {
+      if (mp_cmp(&tb, &ta) != MP_GT) {
+         if ((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY)            goto LBL_ERR;
+         if ((err = mp_add(&q, &tq, &q)) != MP_OKAY)              goto LBL_ERR;
+      }
+      if ((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY)        goto LBL_ERR;
+      if ((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)        goto LBL_ERR;
+   }
 
-  /* now q == quotient and ta == remainder */
-  n  = a->sign;
-  n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
-  if (c != NULL) {
-     mp_exch(c, &q);
-     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
-  }
-  if (d != NULL) {
-     mp_exch(d, &ta);
-     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
-  }
+   /* now q == quotient and ta == remainder */
+   n  = a->sign;
+   n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+   if (c != NULL) {
+      mp_exch(c, &q);
+      c->sign  = MP_IS_ZERO(c) ? MP_ZPOS : n2;
+   }
+   if (d != NULL) {
+      mp_exch(d, &ta);
+      d->sign = MP_IS_ZERO(d) ? MP_ZPOS : n;
+   }
 LBL_ERR:
    mp_clear_multi(&ta, &tb, &tq, &q, NULL);
-   return res;
+   return err;
 }
 
 #else
@@ -100,196 +83,168 @@
  * The overall algorithm is as described as
  * 14.20 from HAC but fixed to treat these cases.
 */
-int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
 {
-  mp_int  q, x, y, t1, t2;
-  int     res, n, t, i, norm, neg;
-
-  /* is divisor zero ? */
-  if (mp_iszero (b) == MP_YES) {
-    return MP_VAL;
-  }
+   mp_int  q, x, y, t1, t2;
+   int     n, t, i, norm;
+   mp_sign neg;
+   mp_err  err;
 
-  /* if a < b then q=0, r = a */
-  if (mp_cmp_mag (a, b) == MP_LT) {
-    if (d != NULL) {
-      res = mp_copy (a, d);
-    } else {
-      res = MP_OKAY;
-    }
-    if (c != NULL) {
-      mp_zero (c);
-    }
-    return res;
-  }
+   /* is divisor zero ? */
+   if (MP_IS_ZERO(b)) {
+      return MP_VAL;
+   }
 
-  if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
-    return res;
-  }
-  q.used = a->used + 2;
-
-  if ((res = mp_init (&t1)) != MP_OKAY) {
-    goto LBL_Q;
-  }
+   /* if a < b then q=0, r = a */
+   if (mp_cmp_mag(a, b) == MP_LT) {
+      if (d != NULL) {
+         err = mp_copy(a, d);
+      } else {
+         err = MP_OKAY;
+      }
+      if (c != NULL) {
+         mp_zero(c);
+      }
+      return err;
+   }
 
-  if ((res = mp_init (&t2)) != MP_OKAY) {
-    goto LBL_T1;
-  }
-
-  if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
-    goto LBL_T2;
-  }
+   if ((err = mp_init_size(&q, a->used + 2)) != MP_OKAY) {
+      return err;
+   }
+   q.used = a->used + 2;
 
-  if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
-    goto LBL_X;
-  }
+   if ((err = mp_init(&t1)) != MP_OKAY)                           goto LBL_Q;
 
-  /* fix the sign */
-  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
-  x.sign = y.sign = MP_ZPOS;
+   if ((err = mp_init(&t2)) != MP_OKAY)                           goto LBL_T1;
+
+   if ((err = mp_init_copy(&x, a)) != MP_OKAY)                    goto LBL_T2;
 
-  /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
-  norm = mp_count_bits(&y) % DIGIT_BIT;
-  if (norm < (int)(DIGIT_BIT-1)) {
-     norm = (DIGIT_BIT-1) - norm;
-     if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
-       goto LBL_Y;
-     }
-     if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
-       goto LBL_Y;
-     }
-  } else {
-     norm = 0;
-  }
+   if ((err = mp_init_copy(&y, b)) != MP_OKAY)                    goto LBL_X;
+
+   /* fix the sign */
+   neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+   x.sign = y.sign = MP_ZPOS;
 
-  /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
-  n = x.used - 1;
-  t = y.used - 1;
-
-  /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
-  if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
-    goto LBL_Y;
-  }
-
-  while (mp_cmp (&x, &y) != MP_LT) {
-    ++(q.dp[n - t]);
-    if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
-      goto LBL_Y;
-    }
-  }
-
-  /* reset y by shifting it back down */
-  mp_rshd (&y, n - t);
+   /* normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT] */
+   norm = mp_count_bits(&y) % MP_DIGIT_BIT;
+   if (norm < (MP_DIGIT_BIT - 1)) {
+      norm = (MP_DIGIT_BIT - 1) - norm;
+      if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY)             goto LBL_Y;
+      if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY)             goto LBL_Y;
+   } else {
+      norm = 0;
+   }
 
-  /* step 3. for i from n down to (t + 1) */
-  for (i = n; i >= (t + 1); i--) {
-    if (i > x.used) {
-      continue;
-    }
+   /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+   n = x.used - 1;
+   t = y.used - 1;
+
+   /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
+   /* y = y*b**{n-t} */
+   if ((err = mp_lshd(&y, n - t)) != MP_OKAY)                     goto LBL_Y;
 
-    /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
-     * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
-    if (x.dp[i] == y.dp[t]) {
-      q.dp[(i - t) - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
-    } else {
-      mp_word tmp;
-      tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
-      tmp |= ((mp_word) x.dp[i - 1]);
-      tmp /= ((mp_word) y.dp[t]);
-      if (tmp > (mp_word) MP_MASK) {
-        tmp = MP_MASK;
-      }
-      q.dp[(i - t) - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
-    }
+   while (mp_cmp(&x, &y) != MP_LT) {
+      ++(q.dp[n - t]);
+      if ((err = mp_sub(&x, &y, &x)) != MP_OKAY)                  goto LBL_Y;
+   }
 
-    /* while (q{i-t-1} * (yt * b + y{t-1})) >
-             xi * b**2 + xi-1 * b + xi-2
+   /* reset y by shifting it back down */
+   mp_rshd(&y, n - t);
 
-       do q{i-t-1} -= 1;
-    */
-    q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1) & MP_MASK;
-    do {
-      q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1) & MP_MASK;
-
-      /* find left hand */
-      mp_zero (&t1);
-      t1.dp[0] = ((t - 1) < 0) ? 0 : y.dp[t - 1];
-      t1.dp[1] = y.dp[t];
-      t1.used = 2;
-      if ((res = mp_mul_d (&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
-        goto LBL_Y;
+   /* step 3. for i from n down to (t + 1) */
+   for (i = n; i >= (t + 1); i--) {
+      if (i > x.used) {
+         continue;
       }
 
-      /* find right hand */
-      t2.dp[0] = ((i - 2) < 0) ? 0 : x.dp[i - 2];
-      t2.dp[1] = ((i - 1) < 0) ? 0 : x.dp[i - 1];
-      t2.dp[2] = x.dp[i];
-      t2.used = 3;
-    } while (mp_cmp_mag(&t1, &t2) == MP_GT);
-
-    /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
-    if ((res = mp_mul_d (&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
-      goto LBL_Y;
-    }
-
-    if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) {
-      goto LBL_Y;
-    }
-
-    if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
-      goto LBL_Y;
-    }
-
-    /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
-    if (x.sign == MP_NEG) {
-      if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
-        goto LBL_Y;
-      }
-      if ((res = mp_lshd (&t1, (i - t) - 1)) != MP_OKAY) {
-        goto LBL_Y;
-      }
-      if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
-        goto LBL_Y;
+      /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
+       * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
+      if (x.dp[i] == y.dp[t]) {
+         q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)MP_DIGIT_BIT) - (mp_digit)1;
+      } else {
+         mp_word tmp;
+         tmp = (mp_word)x.dp[i] << (mp_word)MP_DIGIT_BIT;
+         tmp |= (mp_word)x.dp[i - 1];
+         tmp /= (mp_word)y.dp[t];
+         if (tmp > (mp_word)MP_MASK) {
+            tmp = MP_MASK;
+         }
+         q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)MP_MASK);
       }
 
-      q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1UL) & MP_MASK;
-    }
-  }
+      /* while (q{i-t-1} * (yt * b + y{t-1})) >
+               xi * b**2 + xi-1 * b + xi-2
+
+         do q{i-t-1} -= 1;
+      */
+      q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1uL) & (mp_digit)MP_MASK;
+      do {
+         q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & (mp_digit)MP_MASK;
+
+         /* find left hand */
+         mp_zero(&t1);
+         t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1];
+         t1.dp[1] = y.dp[t];
+         t1.used = 2;
+         if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
 
-  /* now q is the quotient and x is the remainder
-   * [which we have to normalize]
-   */
+         /* find right hand */
+         t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2];
+         t2.dp[1] = x.dp[i - 1]; /* i >= 1 always holds */
+         t2.dp[2] = x.dp[i];
+         t2.used = 3;
+      } while (mp_cmp_mag(&t1, &t2) == MP_GT);
+
+      /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
+      if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y;
 
-  /* get sign before writing to c */
-  x.sign = (x.used == 0) ? MP_ZPOS : a->sign;
+      if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY)           goto LBL_Y;
+
+      if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY)                 goto LBL_Y;
+
+      /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
+      if (x.sign == MP_NEG) {
+         if ((err = mp_copy(&y, &t1)) != MP_OKAY)                 goto LBL_Y;
+         if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY)        goto LBL_Y;
+         if ((err = mp_add(&x, &t1, &x)) != MP_OKAY)              goto LBL_Y;
 
-  if (c != NULL) {
-    mp_clamp (&q);
-    mp_exch (&q, c);
-    c->sign = neg;
-  }
+         q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK;
+      }
+   }
+
+   /* now q is the quotient and x is the remainder
+    * [which we have to normalize]
+    */
+
+   /* get sign before writing to c */
+   x.sign = (x.used == 0) ? MP_ZPOS : a->sign;
+
+   if (c != NULL) {
+      mp_clamp(&q);
+      mp_exch(&q, c);
+      c->sign = neg;
+   }
 
-  if (d != NULL) {
-    if ((res = mp_div_2d (&x, norm, &x, NULL)) != MP_OKAY) {
-      goto LBL_Y;
-    }
-    mp_exch (&x, d);
-  }
+   if (d != NULL) {
+      if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY)       goto LBL_Y;
+      mp_exch(&x, d);
+   }
+
+   err = MP_OKAY;
 
-  res = MP_OKAY;
-
-LBL_Y:mp_clear (&y);
-LBL_X:mp_clear (&x);
-LBL_T2:mp_clear (&t2);
-LBL_T1:mp_clear (&t1);
-LBL_Q:mp_clear (&q);
-  return res;
+LBL_Y:
+   mp_clear(&y);
+LBL_X:
+   mp_clear(&x);
+LBL_T2:
+   mp_clear(&t2);
+LBL_T1:
+   mp_clear(&t1);
+LBL_Q:
+   mp_clear(&q);
+   return err;
 }
 
 #endif
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_div_2.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_div_2.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,68 +1,49 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DIV_2_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* b = a/2 */
-int mp_div_2(mp_int * a, mp_int * b)
+mp_err mp_div_2(const mp_int *a, mp_int *b)
 {
-  int     x, res, oldused;
+   int     x, oldused;
+   mp_digit r, rr, *tmpa, *tmpb;
+   mp_err err;
 
-  /* copy */
-  if (b->alloc < a->used) {
-    if ((res = mp_grow (b, a->used)) != MP_OKAY) {
-      return res;
-    }
-  }
+   /* copy */
+   if (b->alloc < a->used) {
+      if ((err = mp_grow(b, a->used)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  oldused = b->used;
-  b->used = a->used;
-  {
-    mp_digit r, rr, *tmpa, *tmpb;
+   oldused = b->used;
+   b->used = a->used;
 
-    /* source alias */
-    tmpa = a->dp + b->used - 1;
+   /* source alias */
+   tmpa = a->dp + b->used - 1;
 
-    /* dest alias */
-    tmpb = b->dp + b->used - 1;
+   /* dest alias */
+   tmpb = b->dp + b->used - 1;
 
-    /* carry */
-    r = 0;
-    for (x = b->used - 1; x >= 0; x--) {
+   /* carry */
+   r = 0;
+   for (x = b->used - 1; x >= 0; x--) {
       /* get the carry for the next iteration */
-      rr = *tmpa & 1;
+      rr = *tmpa & 1u;
 
       /* shift the current digit, add in carry and store */
-      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+      *tmpb-- = (*tmpa-- >> 1) | (r << (MP_DIGIT_BIT - 1));
 
       /* forward carry to next iteration */
       r = rr;
-    }
+   }
 
-    /* zero excess digits */
-    tmpb = b->dp + b->used;
-    for (x = b->used; x < oldused; x++) {
-      *tmpb++ = 0;
-    }
-  }
-  b->sign = a->sign;
-  mp_clamp (b);
-  return MP_OKAY;
+   /* zero excess digits */
+   MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
+
+   b->sign = a->sign;
+   mp_clamp(b);
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_div_2d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_div_2d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,86 +1,71 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DIV_2D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
-int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
+mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
 {
-  mp_digit D, r, rr;
-  int     x, res;
+   mp_digit D, r, rr;
+   int     x;
+   mp_err err;
 
-  /* if the shift count is <= 0 then we do no work */
-  if (b <= 0) {
-    res = mp_copy (a, c);
-    if (d != NULL) {
-      mp_zero (d);
-    }
-    return res;
-  }
+   /* if the shift count is <= 0 then we do no work */
+   if (b <= 0) {
+      err = mp_copy(a, c);
+      if (d != NULL) {
+         mp_zero(d);
+      }
+      return err;
+   }
 
-  /* copy */
-  if ((res = mp_copy (a, c)) != MP_OKAY) {
-    return res;
-  }
-  /* 'a' should not be used after here - it might be the same as d */
+   /* copy */
+   if ((err = mp_copy(a, c)) != MP_OKAY) {
+      return err;
+   }
+   /* 'a' should not be used after here - it might be the same as d */
 
-  /* get the remainder */
-  if (d != NULL) {
-    if ((res = mp_mod_2d (a, b, d)) != MP_OKAY) {
-      return res;
-    }
-  }
+   /* get the remainder */
+   if (d != NULL) {
+      if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  /* shift by as many digits in the bit count */
-  if (b >= (int)DIGIT_BIT) {
-    mp_rshd (c, b / DIGIT_BIT);
-  }
+   /* shift by as many digits in the bit count */
+   if (b >= MP_DIGIT_BIT) {
+      mp_rshd(c, b / MP_DIGIT_BIT);
+   }
 
-  /* shift any bit count < DIGIT_BIT */
-  D = (mp_digit) (b % DIGIT_BIT);
-  if (D != 0) {
-    mp_digit *tmpc, mask, shift;
+   /* shift any bit count < MP_DIGIT_BIT */
+   D = (mp_digit)(b % MP_DIGIT_BIT);
+   if (D != 0u) {
+      mp_digit *tmpc, mask, shift;
 
-    /* mask */
-    mask = (((mp_digit)1) << D) - 1;
+      /* mask */
+      mask = ((mp_digit)1 << D) - 1uL;
 
-    /* shift for lsb */
-    shift = DIGIT_BIT - D;
+      /* shift for lsb */
+      shift = (mp_digit)MP_DIGIT_BIT - D;
 
-    /* alias */
-    tmpc = c->dp + (c->used - 1);
+      /* alias */
+      tmpc = c->dp + (c->used - 1);
 
-    /* carry */
-    r = 0;
-    for (x = c->used - 1; x >= 0; x--) {
-      /* get the lower  bits of this word in a temp */
-      rr = *tmpc & mask;
+      /* carry */
+      r = 0;
+      for (x = c->used - 1; x >= 0; x--) {
+         /* get the lower  bits of this word in a temp */
+         rr = *tmpc & mask;
 
-      /* shift the current word and mix in the carry bits from the previous word */
-      *tmpc = (*tmpc >> D) | (r << shift);
-      --tmpc;
+         /* shift the current word and mix in the carry bits from the previous word */
+         *tmpc = (*tmpc >> D) | (r << shift);
+         --tmpc;
 
-      /* set the carry to the carry bits of the current word found above */
-      r = rr;
-    }
-  }
-  mp_clamp (c);
-  return MP_OKAY;
+         /* set the carry to the carry bits of the current word found above */
+         r = rr;
+      }
+   }
+   mp_clamp(c);
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_div_3.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_div_3.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,79 +1,63 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DIV_3_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* divide by three (based on routine from MPI and the GMP manual) */
-int
-mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d)
 {
-  mp_int   q;
-  mp_word  w, t;
-  mp_digit b;
-  int      res, ix;
-  
-  /* b = 2**DIGIT_BIT / 3 */
-  b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
+   mp_int   q;
+   mp_word  w, t;
+   mp_digit b;
+   mp_err   err;
+   int      ix;
+
+   /* b = 2**MP_DIGIT_BIT / 3 */
+   b = ((mp_word)1 << (mp_word)MP_DIGIT_BIT) / (mp_word)3;
+
+   if ((err = mp_init_size(&q, a->used)) != MP_OKAY) {
+      return err;
+   }
 
-  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
-     return res;
-  }
-  
-  q.used = a->used;
-  q.sign = a->sign;
-  w = 0;
-  for (ix = a->used - 1; ix >= 0; ix--) {
-     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+   q.used = a->used;
+   q.sign = a->sign;
+   w = 0;
+   for (ix = a->used - 1; ix >= 0; ix--) {
+      w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix];
+
+      if (w >= 3u) {
+         /* multiply w by [1/3] */
+         t = (w * (mp_word)b) >> (mp_word)MP_DIGIT_BIT;
 
-     if (w >= 3) {
-        /* multiply w by [1/3] */
-        t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
-
-        /* now subtract 3 * [w/3] from w, to get the remainder */
-        w -= t+t+t;
+         /* now subtract 3 * [w/3] from w, to get the remainder */
+         w -= t+t+t;
 
-        /* fixup the remainder as required since
-         * the optimization is not exact.
-         */
-        while (w >= 3) {
-           t += 1;
-           w -= 3;
-        }
+         /* fixup the remainder as required since
+          * the optimization is not exact.
+          */
+         while (w >= 3u) {
+            t += 1u;
+            w -= 3u;
+         }
       } else {
-        t = 0;
+         t = 0;
       }
       q.dp[ix] = (mp_digit)t;
-  }
+   }
 
-  /* [optional] store the remainder */
-  if (d != NULL) {
-     *d = (mp_digit)w;
-  }
+   /* [optional] store the remainder */
+   if (d != NULL) {
+      *d = (mp_digit)w;
+   }
 
-  /* [optional] store the quotient */
-  if (c != NULL) {
-     mp_clamp(&q);
-     mp_exch(&q, c);
-  }
-  mp_clear(&q);
-  
-  return res;
+   /* [optional] store the quotient */
+   if (c != NULL) {
+      mp_clamp(&q);
+      mp_exch(&q, c);
+   }
+   mp_clear(&q);
+
+   return err;
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_div_d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_div_d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,115 +1,84 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DIV_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-static int s_is_power_of_two(mp_digit b, int *p)
-{
-   int x;
-
-   /* fast return if no power of two */
-   if ((b == 0) || ((b & (b-1)) != 0)) {
-      return 0;
-   }
-
-   for (x = 0; x < DIGIT_BIT; x++) {
-      if (b == (((mp_digit)1)<<x)) {
-         *p = x;
-         return 1;
-      }
-   }
-   return 0;
-}
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* single digit division (based on routine from MPI) */
-int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d)
 {
-  mp_int  q;
-  mp_word w;
-  mp_digit t;
-  int     res, ix;
-
-  /* cannot divide by zero */
-  if (b == 0) {
-     return MP_VAL;
-  }
+   mp_int  q;
+   mp_word w;
+   mp_digit t;
+   mp_err err;
+   int ix;
 
-  /* quick outs */
-  if ((b == 1) || (mp_iszero(a) == MP_YES)) {
-     if (d != NULL) {
-        *d = 0;
-     }
-     if (c != NULL) {
-        return mp_copy(a, c);
-     }
-     return MP_OKAY;
-  }
+   /* cannot divide by zero */
+   if (b == 0u) {
+      return MP_VAL;
+   }
 
-  /* power of two ? */
-  if (s_is_power_of_two(b, &ix) == 1) {
-     if (d != NULL) {
-        *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
-     }
-     if (c != NULL) {
-        return mp_div_2d(a, ix, c, NULL);
-     }
-     return MP_OKAY;
-  }
+   /* quick outs */
+   if ((b == 1u) || MP_IS_ZERO(a)) {
+      if (d != NULL) {
+         *d = 0;
+      }
+      if (c != NULL) {
+         return mp_copy(a, c);
+      }
+      return MP_OKAY;
+   }
 
-#ifdef BN_MP_DIV_3_C
-  /* three? */
-  if (b == 3) {
-     return mp_div_3(a, c, d);
-  }
-#endif
+   /* power of two ? */
+   if ((b & (b - 1u)) == 0u) {
+      ix = 1;
+      while ((ix < MP_DIGIT_BIT) && (b != (((mp_digit)1)<<ix))) {
+         ix++;
+      }
+      if (d != NULL) {
+         *d = a->dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL);
+      }
+      if (c != NULL) {
+         return mp_div_2d(a, ix, c, NULL);
+      }
+      return MP_OKAY;
+   }
+
+   /* three? */
+   if (MP_HAS(MP_DIV_3) && (b == 3u)) {
+      return mp_div_3(a, c, d);
+   }
+
+   /* no easy answer [c'est la vie].  Just division */
+   if ((err = mp_init_size(&q, a->used)) != MP_OKAY) {
+      return err;
+   }
 
-  /* no easy answer [c'est la vie].  Just division */
-  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
-     return res;
-  }
-  
-  q.used = a->used;
-  q.sign = a->sign;
-  w = 0;
-  for (ix = a->used - 1; ix >= 0; ix--) {
-     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
-     
-     if (w >= b) {
-        t = (mp_digit)(w / b);
-        w -= ((mp_word)t) * ((mp_word)b);
+   q.used = a->used;
+   q.sign = a->sign;
+   w = 0;
+   for (ix = a->used - 1; ix >= 0; ix--) {
+      w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix];
+
+      if (w >= b) {
+         t = (mp_digit)(w / b);
+         w -= (mp_word)t * (mp_word)b;
       } else {
-        t = 0;
+         t = 0;
       }
-      q.dp[ix] = (mp_digit)t;
-  }
-  
-  if (d != NULL) {
-     *d = (mp_digit)w;
-  }
-  
-  if (c != NULL) {
-     mp_clamp(&q);
-     mp_exch(&q, c);
-  }
-  mp_clear(&q);
-  
-  return res;
+      q.dp[ix] = t;
+   }
+
+   if (d != NULL) {
+      *d = (mp_digit)w;
+   }
+
+   if (c != NULL) {
+      mp_clamp(&q);
+      mp_exch(&q, c);
+   }
+   mp_clear(&q);
+
+   return err;
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_dr_is_modulus.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_dr_is_modulus.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,43 +1,27 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DR_IS_MODULUS_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* determines if a number is a valid DR modulus */
-int mp_dr_is_modulus(mp_int *a)
+mp_bool mp_dr_is_modulus(const mp_int *a)
 {
    int ix;
 
    /* must be at least two digits */
    if (a->used < 2) {
-      return 0;
+      return MP_NO;
    }
 
    /* must be of the form b**k - a [a <= b] so all
     * but the first digit must be equal to -1 (mod b).
     */
    for (ix = 1; ix < a->used; ix++) {
-       if (a->dp[ix] != MP_MASK) {
-          return 0;
-       }
+      if (a->dp[ix] != MP_MASK) {
+         return MP_NO;
+      }
    }
-   return 1;
+   return MP_YES;
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_dr_reduce.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_dr_reduce.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,19 +1,7 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DR_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
  *
@@ -29,68 +17,62 @@
  *
  * Input x must be in the range 0 <= x <= (n-1)**2
  */
-int
-mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k)
 {
-  int      err, i, m;
-  mp_word  r;
-  mp_digit mu, *tmpx1, *tmpx2;
+   mp_err      err;
+   int i, m;
+   mp_word  r;
+   mp_digit mu, *tmpx1, *tmpx2;
 
-  /* m = digits in modulus */
-  m = n->used;
+   /* m = digits in modulus */
+   m = n->used;
 
-  /* ensure that "x" has at least 2m digits */
-  if (x->alloc < (m + m)) {
-    if ((err = mp_grow (x, m + m)) != MP_OKAY) {
-      return err;
-    }
-  }
+   /* ensure that "x" has at least 2m digits */
+   if (x->alloc < (m + m)) {
+      if ((err = mp_grow(x, m + m)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-/* top of loop, this is where the code resumes if
- * another reduction pass is required.
- */
+   /* top of loop, this is where the code resumes if
+    * another reduction pass is required.
+    */
 top:
-  /* aliases for digits */
-  /* alias for lower half of x */
-  tmpx1 = x->dp;
+   /* aliases for digits */
+   /* alias for lower half of x */
+   tmpx1 = x->dp;
 
-  /* alias for upper half of x, or x/B**m */
-  tmpx2 = x->dp + m;
+   /* alias for upper half of x, or x/B**m */
+   tmpx2 = x->dp + m;
 
-  /* set carry to zero */
-  mu = 0;
+   /* set carry to zero */
+   mu = 0;
 
-  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
-  for (i = 0; i < m; i++) {
-      r         = (((mp_word)*tmpx2++) * (mp_word)k) + *tmpx1 + mu;
+   /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
+   for (i = 0; i < m; i++) {
+      r         = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu;
       *tmpx1++  = (mp_digit)(r & MP_MASK);
-      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
-  }
+      mu        = (mp_digit)(r >> ((mp_word)MP_DIGIT_BIT));
+   }
 
-  /* set final carry */
-  *tmpx1++ = mu;
+   /* set final carry */
+   *tmpx1++ = mu;
 
-  /* zero words above m */
-  for (i = m + 1; i < x->used; i++) {
-      *tmpx1++ = 0;
-  }
+   /* zero words above m */
+   MP_ZERO_DIGITS(tmpx1, (x->used - m) - 1);
 
-  /* clamp, sub and return */
-  mp_clamp (x);
+   /* clamp, sub and return */
+   mp_clamp(x);
 
-  /* if x >= n then subtract and reduce again
-   * Each successive "recursion" makes the input smaller and smaller.
-   */
-  if (mp_cmp_mag (x, n) != MP_LT) {
-    if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
-      return err;
-    }
-    goto top;
-  }
-  return MP_OKAY;
+   /* if x >= n then subtract and reduce again
+    * Each successive "recursion" makes the input smaller and smaller.
+    */
+   if (mp_cmp_mag(x, n) != MP_LT) {
+      if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
+         return err;
+      }
+      goto top;
+   }
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_dr_setup.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_dr_setup.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,32 +1,15 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DR_SETUP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* determines the setup value */
-void mp_dr_setup(mp_int *a, mp_digit *d)
+void mp_dr_setup(const mp_int *a, mp_digit *d)
 {
-   /* the casts are required if DIGIT_BIT is one less than
-    * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
+   /* the casts are required if MP_DIGIT_BIT is one less than
+    * the number of bits in a mp_digit [e.g. MP_DIGIT_BIT==31]
     */
-   *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - 
-        ((mp_word)a->dp[0]));
+   *d = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - (mp_word)a->dp[0]);
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_error_to_string.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,27 @@
+#include "tommath_private.h"
+#ifdef BN_MP_ERROR_TO_STRING_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* return a char * string for a given code */
+const char *mp_error_to_string(mp_err code)
+{
+   switch (code) {
+   case MP_OKAY:
+      return "Successful";
+   case MP_ERR:
+      return "Unknown error";
+   case MP_MEM:
+      return "Out of heap";
+   case MP_VAL:
+      return "Value out of range";
+   case MP_ITER:
+      return "Max. iterations reached";
+   case MP_BUF:
+      return "Buffer overflow";
+   default:
+      return "Invalid error code";
+   }
+}
+
+#endif
--- a/libtommath/bn_mp_exch.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_exch.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,34 +1,17 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_EXCH_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-/* swap the elements of two integers, for cases where you can't simply swap the 
+/* swap the elements of two integers, for cases where you can't simply swap the
  * mp_int pointers around
  */
-void
-mp_exch (mp_int * a, mp_int * b)
+void mp_exch(mp_int *a, mp_int *b)
 {
-  mp_int  t;
+   mp_int  t;
 
-  t  = *a;
-  *a = *b;
-  *b = t;
+   t  = *a;
+   *a = *b;
+   *b = t;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_export.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_EXPORT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* based on gmp's mpz_export.
- * see http://gmplib.org/manual/Integer-Import-and-Export.html
- */
-int mp_export(void* rop, size_t* countp, int order, size_t size, 
-                                int endian, size_t nails, mp_int* op) {
-	int result;
-	size_t odd_nails, nail_bytes, i, j, bits, count;
-	unsigned char odd_nail_mask;
-
-	mp_int t;
-
-	if ((result = mp_init_copy(&t, op)) != MP_OKAY) {
-		return result;
-	}
-
-	if (endian == 0) {
-		union {
-			unsigned int i;
-			char c[4];
-		} lint;
-		lint.i = 0x01020304;
-
-		endian = (lint.c[0] == 4) ? -1 : 1;
-	}
-
-	odd_nails = (nails % 8);
-	odd_nail_mask = 0xff;
-	for (i = 0; i < odd_nails; ++i) {
-		odd_nail_mask ^= (1 << (7 - i));
-	}
-	nail_bytes = nails / 8;
-
-	bits = mp_count_bits(&t);
-	count = (bits / ((size * 8) - nails)) + (((bits % ((size * 8) - nails)) != 0) ? 1 : 0);
-
-	for (i = 0; i < count; ++i) {
-		for (j = 0; j < size; ++j) {
-			unsigned char* byte = (
-				(unsigned char*)rop + 
-				(((order == -1) ? i : ((count - 1) - i)) * size) +
-				((endian == -1) ? j : ((size - 1) - j))
-			);
-
-			if (j >= (size - nail_bytes)) {
-				*byte = 0;
-				continue;
-			}
-
-			*byte = (unsigned char)((j == ((size - nail_bytes) - 1)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFF));
-
-			if ((result = mp_div_2d(&t, ((j == ((size - nail_bytes) - 1)) ? (8 - odd_nails) : 8), &t, NULL)) != MP_OKAY) {
-				mp_clear(&t);
-				return result;
-			}
-		}
-	}
-
-	mp_clear(&t);
-
-	if (countp != NULL) {
-		*countp = count;
-	}
-
-	return MP_OKAY;
-}
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_expt_d.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_EXPT_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* wrapper function for mp_expt_d_ex() */
-int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
-{
-  return mp_expt_d_ex(a, b, c, 0);
-}
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_expt_d_ex.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_EXPT_D_EX_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* calculate c = a**b  using a square-multiply algorithm */
-int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast)
-{
-  int     res;
-  unsigned int x;
-
-  mp_int  g;
-
-  if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
-    return res;
-  }
-
-  /* set initial result */
-  mp_set (c, 1);
-
-  if (fast != 0) {
-    while (b > 0) {
-      /* if the bit is set multiply */
-      if ((b & 1) != 0) {
-        if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
-          mp_clear (&g);
-          return res;
-        }
-      }
-
-      /* square */
-      if (b > 1) {
-        if ((res = mp_sqr (&g, &g)) != MP_OKAY) {
-          mp_clear (&g);
-          return res;
-        }
-      }
-
-      /* shift to next bit */
-      b >>= 1;
-    }
-  }
-  else {
-    for (x = 0; x < DIGIT_BIT; x++) {
-      /* square */
-      if ((res = mp_sqr (c, c)) != MP_OKAY) {
-        mp_clear (&g);
-        return res;
-      }
-
-      /* if the bit is set multiply */
-      if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
-        if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
-           mp_clear (&g);
-           return res;
-        }
-      }
-
-      /* shift to next bit */
-      b <<= 1;
-    }
-  } /* if ... else */
-
-  mp_clear (&g);
-  return MP_OKAY;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_expt_u32.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,46 @@
+#include "tommath_private.h"
+#ifdef BN_MP_EXPT_U32_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* calculate c = a**b  using a square-multiply algorithm */
+mp_err mp_expt_u32(const mp_int *a, uint32_t b, mp_int *c)
+{
+   mp_err err;
+
+   mp_int  g;
+
+   if ((err = mp_init_copy(&g, a)) != MP_OKAY) {
+      return err;
+   }
+
+   /* set initial result */
+   mp_set(c, 1uL);
+
+   while (b > 0u) {
+      /* if the bit is set multiply */
+      if ((b & 1u) != 0u) {
+         if ((err = mp_mul(c, &g, c)) != MP_OKAY) {
+            goto LBL_ERR;
+         }
+      }
+
+      /* square */
+      if (b > 1u) {
+         if ((err = mp_sqr(&g, &g)) != MP_OKAY) {
+            goto LBL_ERR;
+         }
+      }
+
+      /* shift to next bit */
+      b >>= 1;
+   }
+
+   err = MP_OKAY;
+
+LBL_ERR:
+   mp_clear(&g);
+   return err;
+}
+
+#endif
--- a/libtommath/bn_mp_exptmod.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_exptmod.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,112 +1,76 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_EXPTMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* this is a shell function that calls either the normal or Montgomery
  * exptmod functions.  Originally the call to the montgomery code was
  * embedded in the normal function but that wasted alot of stack space
  * for nothing (since 99% of the time the Montgomery code would be called)
  */
-int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)
 {
-  int dr;
+   int dr;
 
-  /* modulus P must be positive */
-  if (P->sign == MP_NEG) {
-     return MP_VAL;
-  }
+   /* modulus P must be positive */
+   if (P->sign == MP_NEG) {
+      return MP_VAL;
+   }
 
-  /* if exponent X is negative we have to recurse */
-  if (X->sign == MP_NEG) {
-#ifdef BN_MP_INVMOD_C
-     mp_int tmpG, tmpX;
-     int err;
+   /* if exponent X is negative we have to recurse */
+   if (X->sign == MP_NEG) {
+      mp_int tmpG, tmpX;
+      mp_err err;
 
-     /* first compute 1/G mod P */
-     if ((err = mp_init(&tmpG)) != MP_OKAY) {
-        return err;
-     }
-     if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
-        mp_clear(&tmpG);
-        return err;
-     }
+      if (!MP_HAS(MP_INVMOD)) {
+         return MP_VAL;
+      }
+
+      if ((err = mp_init_multi(&tmpG, &tmpX, NULL)) != MP_OKAY) {
+         return err;
+      }
 
-     /* now get |X| */
-     if ((err = mp_init(&tmpX)) != MP_OKAY) {
-        mp_clear(&tmpG);
-        return err;
-     }
-     if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
-        mp_clear_multi(&tmpG, &tmpX, NULL);
-        return err;
-     }
+      /* first compute 1/G mod P */
+      if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+
+      /* now get |X| */
+      if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
 
-     /* and now compute (1/G)**|X| instead of G**X [X < 0] */
-     err = mp_exptmod(&tmpG, &tmpX, P, Y);
-     mp_clear_multi(&tmpG, &tmpX, NULL);
-     return err;
-#else 
-     /* no invmod */
-     return MP_VAL;
-#endif
-  }
+      /* and now compute (1/G)**|X| instead of G**X [X < 0] */
+      err = mp_exptmod(&tmpG, &tmpX, P, Y);
+LBL_ERR:
+      mp_clear_multi(&tmpG, &tmpX, NULL);
+      return err;
+   }
 
-/* modified diminished radix reduction */
-#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
-  if (mp_reduce_is_2k_l(P) == MP_YES) {
-     return s_mp_exptmod(G, X, P, Y, 1);
-  }
-#endif
+   /* modified diminished radix reduction */
+   if (MP_HAS(MP_REDUCE_IS_2K_L) && MP_HAS(MP_REDUCE_2K_L) && MP_HAS(S_MP_EXPTMOD) &&
+       (mp_reduce_is_2k_l(P) == MP_YES)) {
+      return s_mp_exptmod(G, X, P, Y, 1);
+   }
+
+   /* is it a DR modulus? default to no */
+   dr = (MP_HAS(MP_DR_IS_MODULUS) && (mp_dr_is_modulus(P) == MP_YES)) ? 1 : 0;
 
-#ifdef BN_MP_DR_IS_MODULUS_C
-  /* is it a DR modulus? */
-  dr = mp_dr_is_modulus(P);
-#else
-  /* default to no */
-  dr = 0;
-#endif
+   /* if not, is it a unrestricted DR modulus? */
+   if (MP_HAS(MP_REDUCE_IS_2K) && (dr == 0)) {
+      dr = (mp_reduce_is_2k(P) == MP_YES) ? 2 : 0;
+   }
 
-#ifdef BN_MP_REDUCE_IS_2K_C
-  /* if not, is it a unrestricted DR modulus? */
-  if (dr == 0) {
-     dr = mp_reduce_is_2k(P) << 1;
-  }
-#endif
-    
-  /* if the modulus is odd or dr != 0 use the montgomery method */
-#ifdef BN_MP_EXPTMOD_FAST_C
-  if ((mp_isodd (P) == MP_YES) || (dr !=  0)) {
-    return mp_exptmod_fast (G, X, P, Y, dr);
-  } else {
-#endif
-#ifdef BN_S_MP_EXPTMOD_C
-    /* otherwise use the generic Barrett reduction technique */
-    return s_mp_exptmod (G, X, P, Y, 0);
-#else
-    /* no exptmod for evens */
-    return MP_VAL;
-#endif
-#ifdef BN_MP_EXPTMOD_FAST_C
-  }
-#endif
+   /* if the modulus is odd or dr != 0 use the montgomery method */
+   if (MP_HAS(S_MP_EXPTMOD_FAST) && (MP_IS_ODD(P) || (dr != 0))) {
+      return s_mp_exptmod_fast(G, X, P, Y, dr);
+   } else if (MP_HAS(S_MP_EXPTMOD)) {
+      /* otherwise use the generic Barrett reduction technique */
+      return s_mp_exptmod(G, X, P, Y, 0);
+   } else {
+      /* no exptmod for evens */
+      return MP_VAL;
+   }
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_exptmod_fast.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,321 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_EXPTMOD_FAST_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
- *
- * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
- * The value of k changes based on the size of the exponent.
- *
- * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
- */
-
-#ifdef MP_LOW_MEM
-   #define TAB_SIZE 32
-#else
-   #define TAB_SIZE 256
-#endif
-
-int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
-{
-  mp_int  M[TAB_SIZE], res;
-  mp_digit buf, mp;
-  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
-
-  /* use a pointer to the reduction algorithm.  This allows us to use
-   * one of many reduction algorithms without modding the guts of
-   * the code with if statements everywhere.
-   */
-  int     (*redux)(mp_int*,mp_int*,mp_digit);
-
-  /* find window size */
-  x = mp_count_bits (X);
-  if (x <= 7) {
-    winsize = 2;
-  } else if (x <= 36) {
-    winsize = 3;
-  } else if (x <= 140) {
-    winsize = 4;
-  } else if (x <= 450) {
-    winsize = 5;
-  } else if (x <= 1303) {
-    winsize = 6;
-  } else if (x <= 3529) {
-    winsize = 7;
-  } else {
-    winsize = 8;
-  }
-
-#ifdef MP_LOW_MEM
-  if (winsize > 5) {
-     winsize = 5;
-  }
-#endif
-
-  /* init M array */
-  /* init first cell */
-  if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {
-     return err;
-  }
-
-  /* now init the second half of the array */
-  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
-    if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {
-      for (y = 1<<(winsize-1); y < x; y++) {
-        mp_clear (&M[y]);
-      }
-      mp_clear(&M[1]);
-      return err;
-    }
-  }
-
-  /* determine and setup reduction code */
-  if (redmode == 0) {
-#ifdef BN_MP_MONTGOMERY_SETUP_C     
-     /* now setup montgomery  */
-     if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
-        goto LBL_M;
-     }
-#else
-     err = MP_VAL;
-     goto LBL_M;
-#endif
-
-     /* automatically pick the comba one if available (saves quite a few calls/ifs) */
-#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
-     if ((((P->used * 2) + 1) < MP_WARRAY) &&
-          (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
-        redux = fast_mp_montgomery_reduce;
-     } else 
-#endif
-     {
-#ifdef BN_MP_MONTGOMERY_REDUCE_C
-        /* use slower baseline Montgomery method */
-        redux = mp_montgomery_reduce;
-#else
-        err = MP_VAL;
-        goto LBL_M;
-#endif
-     }
-  } else if (redmode == 1) {
-#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
-     /* setup DR reduction for moduli of the form B**k - b */
-     mp_dr_setup(P, &mp);
-     redux = mp_dr_reduce;
-#else
-     err = MP_VAL;
-     goto LBL_M;
-#endif
-  } else {
-#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
-     /* setup DR reduction for moduli of the form 2**k - b */
-     if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
-        goto LBL_M;
-     }
-     redux = mp_reduce_2k;
-#else
-     err = MP_VAL;
-     goto LBL_M;
-#endif
-  }
-
-  /* setup result */
-  if ((err = mp_init_size (&res, P->alloc)) != MP_OKAY) {
-    goto LBL_M;
-  }
-
-  /* create M table
-   *
-
-   *
-   * The first half of the table is not computed though accept for M[0] and M[1]
-   */
-
-  if (redmode == 0) {
-#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
-     /* now we need R mod m */
-     if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
-       goto LBL_RES;
-     }
-
-     /* now set M[1] to G * R mod m */
-     if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
-       goto LBL_RES;
-     }
-#else
-     err = MP_VAL;
-     goto LBL_RES;
-#endif
-  } else {
-     mp_set(&res, 1);
-     if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
-        goto LBL_RES;
-     }
-  }
-
-  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
-  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
-    goto LBL_RES;
-  }
-
-  for (x = 0; x < (winsize - 1); x++) {
-    if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
-      goto LBL_RES;
-    }
-    if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
-      goto LBL_RES;
-    }
-  }
-
-  /* create upper table */
-  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
-    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
-      goto LBL_RES;
-    }
-    if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
-      goto LBL_RES;
-    }
-  }
-
-  /* set initial mode and bit cnt */
-  mode   = 0;
-  bitcnt = 1;
-  buf    = 0;
-  digidx = X->used - 1;
-  bitcpy = 0;
-  bitbuf = 0;
-
-  for (;;) {
-    /* grab next digit as required */
-    if (--bitcnt == 0) {
-      /* if digidx == -1 we are out of digits so break */
-      if (digidx == -1) {
-        break;
-      }
-      /* read next digit and reset bitcnt */
-      buf    = X->dp[digidx--];
-      bitcnt = (int)DIGIT_BIT;
-    }
-
-    /* grab the next msb from the exponent */
-    y     = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
-    buf <<= (mp_digit)1;
-
-    /* if the bit is zero and mode == 0 then we ignore it
-     * These represent the leading zero bits before the first 1 bit
-     * in the exponent.  Technically this opt is not required but it
-     * does lower the # of trivial squaring/reductions used
-     */
-    if ((mode == 0) && (y == 0)) {
-      continue;
-    }
-
-    /* if the bit is zero and mode == 1 then we square */
-    if ((mode == 1) && (y == 0)) {
-      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, mp)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      continue;
-    }
-
-    /* else we add it to the window */
-    bitbuf |= (y << (winsize - ++bitcpy));
-    mode    = 2;
-
-    if (bitcpy == winsize) {
-      /* ok window is filled so square as required and multiply  */
-      /* square first */
-      for (x = 0; x < winsize; x++) {
-        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-        if ((err = redux (&res, P, mp)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-      }
-
-      /* then multiply */
-      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, mp)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-
-      /* empty window and reset */
-      bitcpy = 0;
-      bitbuf = 0;
-      mode   = 1;
-    }
-  }
-
-  /* if bits remain then square/multiply */
-  if ((mode == 2) && (bitcpy > 0)) {
-    /* square then multiply if the bit is set */
-    for (x = 0; x < bitcpy; x++) {
-      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, mp)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-
-      /* get next bit of the window */
-      bitbuf <<= 1;
-      if ((bitbuf & (1 << winsize)) != 0) {
-        /* then multiply */
-        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-        if ((err = redux (&res, P, mp)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-      }
-    }
-  }
-
-  if (redmode == 0) {
-     /* fixup result if Montgomery reduction is used
-      * recall that any value in a Montgomery system is
-      * actually multiplied by R mod n.  So we have
-      * to reduce one more time to cancel out the factor
-      * of R.
-      */
-     if ((err = redux(&res, P, mp)) != MP_OKAY) {
-       goto LBL_RES;
-     }
-  }
-
-  /* swap res with Y */
-  mp_exch (&res, Y);
-  err = MP_OKAY;
-LBL_RES:mp_clear (&res);
-LBL_M:
-  mp_clear(&M[1]);
-  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
-    mp_clear (&M[x]);
-  }
-  return err;
-}
-#endif
-
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_exteuclid.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_exteuclid.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,75 +1,69 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_EXTEUCLID_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* Extended euclidean algorithm of (a, b) produces
    a*u1 + b*u2 = u3
  */
-int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
+mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
 {
-   mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
-   int err;
+   mp_int u1, u2, u3, v1, v2, v3, t1, t2, t3, q, tmp;
+   mp_err err;
 
    if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
       return err;
    }
 
    /* initialize, (u1,u2,u3) = (1,0,a) */
-   mp_set(&u1, 1);
-   if ((err = mp_copy(a, &u3)) != MP_OKAY)                                        { goto LBL_ERR; }
+   mp_set(&u1, 1uL);
+   if ((err = mp_copy(a, &u3)) != MP_OKAY)                        goto LBL_ERR;
 
    /* initialize, (v1,v2,v3) = (0,1,b) */
-   mp_set(&v2, 1);
-   if ((err = mp_copy(b, &v3)) != MP_OKAY)                                        { goto LBL_ERR; }
+   mp_set(&v2, 1uL);
+   if ((err = mp_copy(b, &v3)) != MP_OKAY)                        goto LBL_ERR;
 
    /* loop while v3 != 0 */
-   while (mp_iszero(&v3) == MP_NO) {
-       /* q = u3/v3 */
-       if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY)                         { goto LBL_ERR; }
+   while (!MP_IS_ZERO(&v3)) {
+      /* q = u3/v3 */
+      if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY)          goto LBL_ERR;
 
-       /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
-       if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY)                              { goto LBL_ERR; }
-       if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY)                             { goto LBL_ERR; }
-       if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY)                              { goto LBL_ERR; }
-       if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY)                             { goto LBL_ERR; }
-       if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY)                              { goto LBL_ERR; }
-       if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY)                             { goto LBL_ERR; }
+      /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
+      if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY)               goto LBL_ERR;
+      if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY)              goto LBL_ERR;
+      if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY)               goto LBL_ERR;
+      if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY)              goto LBL_ERR;
+      if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY)               goto LBL_ERR;
+      if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY)              goto LBL_ERR;
 
-       /* (u1,u2,u3) = (v1,v2,v3) */
-       if ((err = mp_copy(&v1, &u1)) != MP_OKAY)                                  { goto LBL_ERR; }
-       if ((err = mp_copy(&v2, &u2)) != MP_OKAY)                                  { goto LBL_ERR; }
-       if ((err = mp_copy(&v3, &u3)) != MP_OKAY)                                  { goto LBL_ERR; }
+      /* (u1,u2,u3) = (v1,v2,v3) */
+      if ((err = mp_copy(&v1, &u1)) != MP_OKAY)                   goto LBL_ERR;
+      if ((err = mp_copy(&v2, &u2)) != MP_OKAY)                   goto LBL_ERR;
+      if ((err = mp_copy(&v3, &u3)) != MP_OKAY)                   goto LBL_ERR;
 
-       /* (v1,v2,v3) = (t1,t2,t3) */
-       if ((err = mp_copy(&t1, &v1)) != MP_OKAY)                                  { goto LBL_ERR; }
-       if ((err = mp_copy(&t2, &v2)) != MP_OKAY)                                  { goto LBL_ERR; }
-       if ((err = mp_copy(&t3, &v3)) != MP_OKAY)                                  { goto LBL_ERR; }
+      /* (v1,v2,v3) = (t1,t2,t3) */
+      if ((err = mp_copy(&t1, &v1)) != MP_OKAY)                   goto LBL_ERR;
+      if ((err = mp_copy(&t2, &v2)) != MP_OKAY)                   goto LBL_ERR;
+      if ((err = mp_copy(&t3, &v3)) != MP_OKAY)                   goto LBL_ERR;
    }
 
    /* make sure U3 >= 0 */
    if (u3.sign == MP_NEG) {
-       if ((err = mp_neg(&u1, &u1)) != MP_OKAY)                                   { goto LBL_ERR; }
-       if ((err = mp_neg(&u2, &u2)) != MP_OKAY)                                   { goto LBL_ERR; }
-       if ((err = mp_neg(&u3, &u3)) != MP_OKAY)                                   { goto LBL_ERR; }
+      if ((err = mp_neg(&u1, &u1)) != MP_OKAY)                    goto LBL_ERR;
+      if ((err = mp_neg(&u2, &u2)) != MP_OKAY)                    goto LBL_ERR;
+      if ((err = mp_neg(&u3, &u3)) != MP_OKAY)                    goto LBL_ERR;
    }
 
    /* copy result out */
-   if (U1 != NULL) { mp_exch(U1, &u1); }
-   if (U2 != NULL) { mp_exch(U2, &u2); }
-   if (U3 != NULL) { mp_exch(U3, &u3); }
+   if (U1 != NULL) {
+      mp_exch(U1, &u1);
+   }
+   if (U2 != NULL) {
+      mp_exch(U2, &u2);
+   }
+   if (U3 != NULL) {
+      mp_exch(U3, &u3);
+   }
 
    err = MP_OKAY;
 LBL_ERR:
@@ -77,7 +71,3 @@
    return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_fread.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_fread.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,69 +1,60 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_FREAD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-#ifndef LTM_NO_FILE
+#ifndef MP_NO_FILE
 /* read a bigint from a file stream in ASCII */
-int mp_fread(mp_int *a, int radix, FILE *stream)
+mp_err mp_fread(mp_int *a, int radix, FILE *stream)
 {
-   int err, ch, neg, y;
-   
-   /* clear a */
-   mp_zero(a);
-   
+   mp_err err;
+   mp_sign neg;
+
    /* if first digit is - then set negative */
-   ch = fgetc(stream);
-   if (ch == '-') {
+   int ch = fgetc(stream);
+   if (ch == (int)'-') {
       neg = MP_NEG;
       ch = fgetc(stream);
    } else {
       neg = MP_ZPOS;
    }
-   
-   for (;;) {
-      /* find y in the radix map */
-      for (y = 0; y < radix; y++) {
-          if (mp_s_rmap[y] == ch) {
-             break;
-          }
-      }
-      if (y == radix) {
+
+   /* no digits, return error */
+   if (ch == EOF) {
+      return MP_ERR;
+   }
+
+   /* clear a */
+   mp_zero(a);
+
+   do {
+      int y;
+      unsigned pos = (unsigned)(ch - (int)'(');
+      if (mp_s_rmap_reverse_sz < pos) {
          break;
       }
-      
+
+      y = (int)mp_s_rmap_reverse[pos];
+
+      if ((y == 0xff) || (y >= radix)) {
+         break;
+      }
+
       /* shift up and add */
-      if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
-         return err;
-      }
-      if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
+      if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
          return err;
       }
-      
-      ch = fgetc(stream);
-   }
-   if (mp_cmp_d(a, 0) != MP_EQ) {
+      if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
+         return err;
+      }
+   } while ((ch = fgetc(stream)) != EOF);
+
+   if (a->used != 0) {
       a->sign = neg;
    }
-   
+
    return MP_OKAY;
 }
 #endif
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_from_sbin.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,25 @@
+#include "tommath_private.h"
+#ifdef BN_MP_FROM_SBIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* read signed bin, big endian, first byte is 0==positive or 1==negative */
+mp_err mp_from_sbin(mp_int *a, const unsigned char *buf, size_t size)
+{
+   mp_err err;
+
+   /* read magnitude */
+   if ((err = mp_from_ubin(a, buf + 1, size - 1u)) != MP_OKAY) {
+      return err;
+   }
+
+   /* first byte is 0 for positive, non-zero for negative */
+   if (buf[0] == (unsigned char)0) {
+      a->sign = MP_ZPOS;
+   } else {
+      a->sign = MP_NEG;
+   }
+
+   return MP_OKAY;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_from_ubin.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,39 @@
+#include "tommath_private.h"
+#ifdef BN_MP_FROM_UBIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* reads a unsigned char array, assumes the msb is stored first [big endian] */
+mp_err mp_from_ubin(mp_int *a, const unsigned char *buf, size_t size)
+{
+   mp_err err;
+
+   /* make sure there are at least two digits */
+   if (a->alloc < 2) {
+      if ((err = mp_grow(a, 2)) != MP_OKAY) {
+         return err;
+      }
+   }
+
+   /* zero the int */
+   mp_zero(a);
+
+   /* read the bytes in */
+   while (size-- > 0u) {
+      if ((err = mp_mul_2d(a, 8, a)) != MP_OKAY) {
+         return err;
+      }
+
+#ifndef MP_8BIT
+      a->dp[0] |= *buf++;
+      a->used += 1;
+#else
+      a->dp[0] = (*buf & MP_MASK);
+      a->dp[1] |= ((*buf++ >> 7) & 1u);
+      a->used += 2;
+#endif
+   }
+   mp_clamp(a);
+   return MP_OKAY;
+}
+#endif
--- a/libtommath/bn_mp_fwrite.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_fwrite.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,54 +1,45 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_FWRITE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-#ifndef LTM_NO_FILE
-int mp_fwrite(mp_int *a, int radix, FILE *stream)
+#ifndef MP_NO_FILE
+mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream)
 {
    char *buf;
-   int err, len, x;
-   
-   if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
-      return err;
+   mp_err err;
+   int len;
+   size_t written;
+
+   /* TODO: this function is not in this PR */
+   if (MP_HAS(MP_RADIX_SIZE_OVERESTIMATE)) {
+      /* if ((err = mp_radix_size_overestimate(&t, base, &len)) != MP_OKAY)      goto LBL_ERR; */
+   } else {
+      if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
+         return err;
+      }
    }
 
-   buf = OPT_CAST(char) XMALLOC (len);
+   buf = (char *) MP_MALLOC((size_t)len);
    if (buf == NULL) {
       return MP_MEM;
    }
-   
-   if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
-      XFREE (buf);
-      return err;
+
+   if ((err = mp_to_radix(a, buf, (size_t)len, &written, radix)) != MP_OKAY) {
+      goto LBL_ERR;
    }
-   
-   for (x = 0; x < len; x++) {
-       if (fputc(buf[x], stream) == EOF) {
-          XFREE (buf);
-          return MP_VAL;
-       }
+
+   if (fwrite(buf, written, 1uL, stream) != 1uL) {
+      err = MP_ERR;
+      goto LBL_ERR;
    }
-   
-   XFREE (buf);
-   return MP_OKAY;
+   err = MP_OKAY;
+
+
+LBL_ERR:
+   MP_FREE_BUFFER(buf, (size_t)len);
+   return err;
 }
 #endif
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_gcd.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_gcd.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,105 +1,92 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_GCD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* Greatest Common Divisor using the binary method */
-int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
+mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  mp_int  u, v;
-  int     k, u_lsb, v_lsb, res;
+   mp_int  u, v;
+   int     k, u_lsb, v_lsb;
+   mp_err err;
 
-  /* either zero than gcd is the largest */
-  if (mp_iszero (a) == MP_YES) {
-    return mp_abs (b, c);
-  }
-  if (mp_iszero (b) == MP_YES) {
-    return mp_abs (a, c);
-  }
+   /* either zero than gcd is the largest */
+   if (MP_IS_ZERO(a)) {
+      return mp_abs(b, c);
+   }
+   if (MP_IS_ZERO(b)) {
+      return mp_abs(a, c);
+   }
 
-  /* get copies of a and b we can modify */
-  if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
-    return res;
-  }
+   /* get copies of a and b we can modify */
+   if ((err = mp_init_copy(&u, a)) != MP_OKAY) {
+      return err;
+   }
 
-  if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
-    goto LBL_U;
-  }
+   if ((err = mp_init_copy(&v, b)) != MP_OKAY) {
+      goto LBL_U;
+   }
 
-  /* must be positive for the remainder of the algorithm */
-  u.sign = v.sign = MP_ZPOS;
+   /* must be positive for the remainder of the algorithm */
+   u.sign = v.sign = MP_ZPOS;
 
-  /* B1.  Find the common power of two for u and v */
-  u_lsb = mp_cnt_lsb(&u);
-  v_lsb = mp_cnt_lsb(&v);
-  k     = MIN(u_lsb, v_lsb);
+   /* B1.  Find the common power of two for u and v */
+   u_lsb = mp_cnt_lsb(&u);
+   v_lsb = mp_cnt_lsb(&v);
+   k     = MP_MIN(u_lsb, v_lsb);
 
-  if (k > 0) {
-     /* divide the power of two out */
-     if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
-        goto LBL_V;
-     }
+   if (k > 0) {
+      /* divide the power of two out */
+      if ((err = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
+         goto LBL_V;
+      }
 
-     if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
-        goto LBL_V;
-     }
-  }
+      if ((err = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
+         goto LBL_V;
+      }
+   }
 
-  /* divide any remaining factors of two out */
-  if (u_lsb != k) {
-     if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
-        goto LBL_V;
-     }
-  }
+   /* divide any remaining factors of two out */
+   if (u_lsb != k) {
+      if ((err = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
+         goto LBL_V;
+      }
+   }
 
-  if (v_lsb != k) {
-     if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
-        goto LBL_V;
-     }
-  }
+   if (v_lsb != k) {
+      if ((err = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
+         goto LBL_V;
+      }
+   }
+
+   while (!MP_IS_ZERO(&v)) {
+      /* make sure v is the largest */
+      if (mp_cmp_mag(&u, &v) == MP_GT) {
+         /* swap u and v to make sure v is >= u */
+         mp_exch(&u, &v);
+      }
 
-  while (mp_iszero(&v) == MP_NO) {
-     /* make sure v is the largest */
-     if (mp_cmp_mag(&u, &v) == MP_GT) {
-        /* swap u and v to make sure v is >= u */
-        mp_exch(&u, &v);
-     }
-     
-     /* subtract smallest from largest */
-     if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
-        goto LBL_V;
-     }
-     
-     /* Divide out all factors of two */
-     if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
-        goto LBL_V;
-     } 
-  } 
+      /* subtract smallest from largest */
+      if ((err = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
+         goto LBL_V;
+      }
+
+      /* Divide out all factors of two */
+      if ((err = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
+         goto LBL_V;
+      }
+   }
 
-  /* multiply by 2**k which we divided out at the beginning */
-  if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
-     goto LBL_V;
-  }
-  c->sign = MP_ZPOS;
-  res = MP_OKAY;
-LBL_V:mp_clear (&u);
-LBL_U:mp_clear (&v);
-  return res;
+   /* multiply by 2**k which we divided out at the beginning */
+   if ((err = mp_mul_2d(&u, k, c)) != MP_OKAY) {
+      goto LBL_V;
+   }
+   c->sign = MP_ZPOS;
+   err = MP_OKAY;
+LBL_V:
+   mp_clear(&u);
+LBL_U:
+   mp_clear(&v);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_i32.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_I32_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_SIGNED(mp_get_i32, mp_get_mag_u32, int32_t, uint32_t)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_i64.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_I64_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_SIGNED(mp_get_i64, mp_get_mag_u64, int64_t, uint64_t)
+#endif
--- a/libtommath/bn_mp_get_int.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_GET_INT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* get the lower 32-bits of an mp_int */
-unsigned long mp_get_int(mp_int * a)
-{
-  int i;
-  mp_min_u32 res;
-
-  if (a->used == 0) {
-     return 0;
-  }
-
-  /* get number of digits of the lsb we have to read */
-  i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
-
-  /* get most significant digit of result */
-  res = DIGIT(a,i);
-
-  while (--i >= 0) {
-    res = (res << DIGIT_BIT) | DIGIT(a,i);
-  }
-
-  /* force result to 32-bits always so it is consistent on non 32-bit platforms */
-  return res & 0xFFFFFFFFUL;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_l.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_SIGNED(mp_get_l, mp_get_mag_ul, long, unsigned long)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_ll.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_LL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_SIGNED(mp_get_ll, mp_get_mag_ull, long long, unsigned long long)
+#endif
--- a/libtommath/bn_mp_get_long.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_GET_LONG_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* get the lower unsigned long of an mp_int, platform dependent */
-unsigned long mp_get_long(mp_int * a)
-{
-  int i;
-  unsigned long res;
-
-  if (a->used == 0) {
-     return 0;
-  }
-
-  /* get number of digits of the lsb we have to read */
-  i = MIN(a->used,(int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
-
-  /* get most significant digit of result */
-  res = DIGIT(a,i);
-
-#if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32)
-  while (--i >= 0) {
-    res = (res << DIGIT_BIT) | DIGIT(a,i);
-  }
-#endif
-  return res;
-}
-#endif
--- a/libtommath/bn_mp_get_long_long.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_GET_LONG_LONG_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* get the lower unsigned long long of an mp_int, platform dependent */
-unsigned long long mp_get_long_long (mp_int * a)
-{
-  int i;
-  unsigned long long res;
-
-  if (a->used == 0) {
-     return 0;
-  }
-
-  /* get number of digits of the lsb we have to read */
-  i = MIN(a->used,(int)(((sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
-
-  /* get most significant digit of result */
-  res = DIGIT(a,i);
-
-#if DIGIT_BIT < 64
-  while (--i >= 0) {
-    res = (res << DIGIT_BIT) | DIGIT(a,i);
-  }
-#endif
-  return res;
-}
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_mag_u32.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_MAG_U32_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_MAG(mp_get_mag_u32, uint32_t)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_mag_u64.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_MAG_U64_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_MAG(mp_get_mag_u64, uint64_t)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_mag_ul.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_MAG_UL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_MAG(mp_get_mag_ul, unsigned long)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_get_mag_ull.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_GET_MAG_ULL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_GET_MAG(mp_get_mag_ull, unsigned long long)
+#endif
--- a/libtommath/bn_mp_grow.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_grow.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,57 +1,38 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_GROW_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* grow as required */
-int mp_grow (mp_int * a, int size)
+mp_err mp_grow(mp_int *a, int size)
 {
-  int     i;
-  mp_digit *tmp;
-
-  /* if the alloc size is smaller alloc more ram */
-  if (a->alloc < size) {
-    /* ensure there are always at least MP_PREC digits extra on top */
-    size += (MP_PREC * 2) - (size % MP_PREC);
+   int     i;
+   mp_digit *tmp;
 
-    /* reallocate the array a->dp
-     *
-     * We store the return in a temporary variable
-     * in case the operation failed we don't want
-     * to overwrite the dp member of a.
-     */
-    tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
-    if (tmp == NULL) {
-      /* reallocation failed but "a" is still valid [can be freed] */
-      return MP_MEM;
-    }
+   /* if the alloc size is smaller alloc more ram */
+   if (a->alloc < size) {
+      /* reallocate the array a->dp
+       *
+       * We store the return in a temporary variable
+       * in case the operation failed we don't want
+       * to overwrite the dp member of a.
+       */
+      tmp = (mp_digit *) MP_REALLOC(a->dp,
+                                    (size_t)a->alloc * sizeof(mp_digit),
+                                    (size_t)size * sizeof(mp_digit));
+      if (tmp == NULL) {
+         /* reallocation failed but "a" is still valid [can be freed] */
+         return MP_MEM;
+      }
 
-    /* reallocation succeeded so set a->dp */
-    a->dp = tmp;
+      /* reallocation succeeded so set a->dp */
+      a->dp = tmp;
 
-    /* zero excess digits */
-    i        = a->alloc;
-    a->alloc = size;
-    for (; i < a->alloc; i++) {
-      a->dp[i] = 0;
-    }
-  }
-  return MP_OKAY;
+      /* zero excess digits */
+      i        = a->alloc;
+      a->alloc = size;
+      MP_ZERO_DIGITS(a->dp + i, a->alloc - i);
+   }
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_import.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_IMPORT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* based on gmp's mpz_import.
- * see http://gmplib.org/manual/Integer-Import-and-Export.html
- */
-int mp_import(mp_int* rop, size_t count, int order, size_t size, 
-                            int endian, size_t nails, const void* op) {
-	int result;
-	size_t odd_nails, nail_bytes, i, j;
-	unsigned char odd_nail_mask;
-
-	mp_zero(rop);
-
-	if (endian == 0) {
-		union {
-			unsigned int i;
-			char c[4];
-		} lint;
-		lint.i = 0x01020304;
-
-		endian = (lint.c[0] == 4) ? -1 : 1;
-	}
-
-	odd_nails = (nails % 8);
-	odd_nail_mask = 0xff;
-	for (i = 0; i < odd_nails; ++i) {
-		odd_nail_mask ^= (1 << (7 - i));
-	}
-	nail_bytes = nails / 8;
-
-	for (i = 0; i < count; ++i) {
-		for (j = 0; j < (size - nail_bytes); ++j) {
-			unsigned char byte = *(
-					(unsigned char*)op + 
-					(((order == 1) ? i : ((count - 1) - i)) * size) +
-					((endian == 1) ? (j + nail_bytes) : (((size - 1) - j) - nail_bytes))
-				);
-
-			if (
-				(result = mp_mul_2d(rop, ((j == 0) ? (8 - odd_nails) : 8), rop)) != MP_OKAY) {
-				return result;
-			}
-
-			rop->dp[0] |= (j == 0) ? (byte & odd_nail_mask) : byte;
-			rop->used  += 1;
-		}
-	}
-
-	mp_clamp(rop);
-
-	return MP_OKAY;
-}
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_incr.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,30 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INCR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* Increment "a" by one like "a++". Changes input! */
+mp_err mp_incr(mp_int *a)
+{
+   if (MP_IS_ZERO(a)) {
+      mp_set(a,1uL);
+      return MP_OKAY;
+   } else if (a->sign == MP_NEG) {
+      mp_err err;
+      a->sign = MP_ZPOS;
+      if ((err = mp_decr(a)) != MP_OKAY) {
+         return err;
+      }
+      /* There is no -0 in LTM */
+      if (!MP_IS_ZERO(a)) {
+         a->sign = MP_NEG;
+      }
+      return MP_OKAY;
+   } else if (a->dp[0] < MP_DIGIT_MAX) {
+      a->dp[0]++;
+      return MP_OKAY;
+   } else {
+      return mp_add_d(a, 1uL,a);
+   }
+}
+#endif
--- a/libtommath/bn_mp_init.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_init.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,46 +1,23 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_INIT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* init a new mp_int */
-int mp_init (mp_int * a)
+mp_err mp_init(mp_int *a)
 {
-  int i;
-
-  /* allocate memory required and clear it */
-  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
-  if (a->dp == NULL) {
-    return MP_MEM;
-  }
+   /* allocate memory required and clear it */
+   a->dp = (mp_digit *) MP_CALLOC((size_t)MP_PREC, sizeof(mp_digit));
+   if (a->dp == NULL) {
+      return MP_MEM;
+   }
 
-  /* set the digits to zero */
-  for (i = 0; i < MP_PREC; i++) {
-      a->dp[i] = 0;
-  }
+   /* set the used to zero, allocated digits to the default precision
+    * and sign to positive */
+   a->used  = 0;
+   a->alloc = MP_PREC;
+   a->sign  = MP_ZPOS;
 
-  /* set the used to zero, allocated digits to the default precision
-   * and sign to positive */
-  a->used  = 0;
-  a->alloc = MP_PREC;
-  a->sign  = MP_ZPOS;
-
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_init_copy.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_init_copy.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,37 +1,21 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_INIT_COPY_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* creates "a" then copies b into it */
-int mp_init_copy (mp_int * a, mp_int * b)
+mp_err mp_init_copy(mp_int *a, const mp_int *b)
 {
-  int     res;
+   mp_err     err;
 
-  if ((res = mp_init_size (a, b->used)) != MP_OKAY) {
-    return res;
-  }
+   if ((err = mp_init_size(a, b->used)) != MP_OKAY) {
+      return err;
+   }
 
-  if((res = mp_copy (b, a)) != MP_OKAY) {
-    mp_clear(a);
-  }
+   if ((err = mp_copy(b, a)) != MP_OKAY) {
+      mp_clear(a);
+   }
 
-  return res;
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_i32.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_I32_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_i32, mp_set_i32, int32_t)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_i64.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_I64_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_i64, mp_set_i64, int64_t)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_l.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_l, mp_set_l, long)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_ll.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_LL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_ll, mp_set_ll, long long)
+#endif
--- a/libtommath/bn_mp_init_multi.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_init_multi.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,56 +1,41 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_INIT_MULTI_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
 #include <stdarg.h>
 
-int mp_init_multi(mp_int *mp, ...) 
+mp_err mp_init_multi(mp_int *mp, ...)
 {
-    mp_err res = MP_OKAY;      /* Assume ok until proven otherwise */
-    int n = 0;                 /* Number of ok inits */
-    mp_int* cur_arg = mp;
-    va_list args;
+   mp_err err = MP_OKAY;      /* Assume ok until proven otherwise */
+   int n = 0;                 /* Number of ok inits */
+   mp_int *cur_arg = mp;
+   va_list args;
+
+   va_start(args, mp);        /* init args to next argument from caller */
+   while (cur_arg != NULL) {
+      if (mp_init(cur_arg) != MP_OKAY) {
+         /* Oops - error! Back-track and mp_clear what we already
+            succeeded in init-ing, then return error.
+         */
+         va_list clean_args;
 
-    va_start(args, mp);        /* init args to next argument from caller */
-    while (cur_arg != NULL) {
-        if (mp_init(cur_arg) != MP_OKAY) {
-            /* Oops - error! Back-track and mp_clear what we already
-               succeeded in init-ing, then return error.
-            */
-            va_list clean_args;
-            
-            /* now start cleaning up */            
-            cur_arg = mp;
-            va_start(clean_args, mp);
-            while (n-- != 0) {
-                mp_clear(cur_arg);
-                cur_arg = va_arg(clean_args, mp_int*);
-            }
-            va_end(clean_args);
-            res = MP_MEM;
-            break;
-        }
-        n++;
-        cur_arg = va_arg(args, mp_int*);
-    }
-    va_end(args);
-    return res;                /* Assumed ok, if error flagged above. */
+         /* now start cleaning up */
+         cur_arg = mp;
+         va_start(clean_args, mp);
+         while (n-- != 0) {
+            mp_clear(cur_arg);
+            cur_arg = va_arg(clean_args, mp_int *);
+         }
+         va_end(clean_args);
+         err = MP_MEM;
+         break;
+      }
+      n++;
+      cur_arg = va_arg(args, mp_int *);
+   }
+   va_end(args);
+   return err;                /* Assumed ok, if error flagged above. */
 }
 
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_init_set.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_init_set.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,32 +1,16 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_INIT_SET_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* initialize and set a digit */
-int mp_init_set (mp_int * a, mp_digit b)
+mp_err mp_init_set(mp_int *a, mp_digit b)
 {
-  int err;
-  if ((err = mp_init(a)) != MP_OKAY) {
-     return err;
-  }
-  mp_set(a, b);
-  return err;
+   mp_err err;
+   if ((err = mp_init(a)) != MP_OKAY) {
+      return err;
+   }
+   mp_set(a, b);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_init_set_int.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_INIT_SET_INT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* initialize and set a digit */
-int mp_init_set_int (mp_int * a, unsigned long b)
-{
-  int err;
-  if ((err = mp_init(a)) != MP_OKAY) {
-     return err;
-  }
-  return mp_set_int(a, b);
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_init_size.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_init_size.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,48 +1,24 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_INIT_SIZE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* init an mp_init for a given size */
-int mp_init_size (mp_int * a, int size)
+mp_err mp_init_size(mp_int *a, int size)
 {
-  int x;
+   size = MP_MAX(MP_MIN_PREC, size);
 
-  /* pad size so there are always extra digits */
-  size += (MP_PREC * 2) - (size % MP_PREC);	
-  
-  /* alloc mem */
-  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
-  if (a->dp == NULL) {
-    return MP_MEM;
-  }
+   /* alloc mem */
+   a->dp = (mp_digit *) MP_CALLOC((size_t)size, sizeof(mp_digit));
+   if (a->dp == NULL) {
+      return MP_MEM;
+   }
 
-  /* set the members */
-  a->used  = 0;
-  a->alloc = size;
-  a->sign  = MP_ZPOS;
+   /* set the members */
+   a->used  = 0;
+   a->alloc = size;
+   a->sign  = MP_ZPOS;
 
-  /* zero the digits */
-  for (x = 0; x < size; x++) {
-      a->dp[x] = 0;
-  }
-
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_u32.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_U32_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_u32, mp_set_u32, uint32_t)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_u64.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_U64_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_u64, mp_set_u64, uint64_t)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_ul.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_UL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_ul, mp_set_ul, unsigned long)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_init_ull.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,7 @@
+#include "tommath_private.h"
+#ifdef BN_MP_INIT_ULL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+MP_INIT_INT(mp_init_ull, mp_set_ull, unsigned long long)
+#endif
--- a/libtommath/bn_mp_invmod.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_invmod.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,43 +1,23 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_INVMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* hac 14.61, pp608 */
-int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  /* b cannot be negative */
-  if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) {
-    return MP_VAL;
-  }
+   /* b cannot be negative and has to be >1 */
+   if ((b->sign == MP_NEG) || (mp_cmp_d(b, 1uL) != MP_GT)) {
+      return MP_VAL;
+   }
 
-#ifdef BN_FAST_MP_INVMOD_C
-  /* if the modulus is odd we can use a faster routine instead */
-  if ((mp_isodd(b) == MP_YES) && (mp_cmp_d(b, 1) != MP_EQ)) {
-    return fast_mp_invmod (a, b, c);
-  }
-#endif
+   /* if the modulus is odd we can use a faster routine instead */
+   if (MP_HAS(S_MP_INVMOD_FAST) && MP_IS_ODD(b)) {
+      return s_mp_invmod_fast(a, b, c);
+   }
 
-#ifdef BN_MP_INVMOD_SLOW_C
-  return mp_invmod_slow(a, b, c);
-#else
-  return MP_VAL;
-#endif
+   return MP_HAS(S_MP_INVMOD_SLOW)
+          ? s_mp_invmod_slow(a, b, c)
+          : MP_VAL;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_invmod_slow.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_INVMOD_SLOW_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* hac 14.61, pp608 */
-int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
-{
-  mp_int  x, y, u, v, A, B, C, D;
-  int     res;
-
-  /* b cannot be negative */
-  if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) {
-    return MP_VAL;
-  }
-
-  /* init temps */
-  if ((res = mp_init_multi(&x, &y, &u, &v, 
-                           &A, &B, &C, &D, NULL)) != MP_OKAY) {
-     return res;
-  }
-
-  /* x = a, y = b */
-  if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
-      goto LBL_ERR;
-  }
-  if ((res = mp_copy (b, &y)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-
-  /* 2. [modified] if x,y are both even then return an error! */
-  if ((mp_iseven (&x) == MP_YES) && (mp_iseven (&y) == MP_YES)) {
-    res = MP_VAL;
-    goto LBL_ERR;
-  }
-
-  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
-  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  mp_set (&A, 1);
-  mp_set (&D, 1);
-
-top:
-  /* 4.  while u is even do */
-  while (mp_iseven (&u) == MP_YES) {
-    /* 4.1 u = u/2 */
-    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 4.2 if A or B is odd then */
-    if ((mp_isodd (&A) == MP_YES) || (mp_isodd (&B) == MP_YES)) {
-      /* A = (A+y)/2, B = (B-x)/2 */
-      if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-    }
-    /* A = A/2, B = B/2 */
-    if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 5.  while v is even do */
-  while (mp_iseven (&v) == MP_YES) {
-    /* 5.1 v = v/2 */
-    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 5.2 if C or D is odd then */
-    if ((mp_isodd (&C) == MP_YES) || (mp_isodd (&D) == MP_YES)) {
-      /* C = (C+y)/2, D = (D-x)/2 */
-      if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-    }
-    /* C = C/2, D = D/2 */
-    if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 6.  if u >= v then */
-  if (mp_cmp (&u, &v) != MP_LT) {
-    /* u = u - v, A = A - C, B = B - D */
-    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  } else {
-    /* v - v - u, C = C - A, D = D - B */
-    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* if not zero goto step 4 */
-  if (mp_iszero (&u) == MP_NO)
-    goto top;
-
-  /* now a = C, b = D, gcd == g*v */
-
-  /* if v != 1 then there is no inverse */
-  if (mp_cmp_d (&v, 1) != MP_EQ) {
-    res = MP_VAL;
-    goto LBL_ERR;
-  }
-
-  /* if its too low */
-  while (mp_cmp_d(&C, 0) == MP_LT) {
-      if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-  }
-  
-  /* too big */
-  while (mp_cmp_mag(&C, b) != MP_LT) {
-      if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-  }
-  
-  /* C is now the inverse */
-  mp_exch (&C, c);
-  res = MP_OKAY;
-LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
-  return res;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_is_square.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_is_square.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,109 +1,93 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_IS_SQUARE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* Check if remainders are possible squares - fast exclude non-squares */
 static const char rem_128[128] = {
- 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
+   0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+   0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+   1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+   1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+   0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+   1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+   1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+   1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
 };
 
 static const char rem_105[105] = {
- 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
- 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
+   0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+   0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
+   0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+   1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+   0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+   1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
+   1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
 };
 
 /* Store non-zero to ret if arg is square, and zero if not */
-int mp_is_square(mp_int *arg,int *ret) 
+mp_err mp_is_square(const mp_int *arg, mp_bool *ret)
 {
-  int           res;
-  mp_digit      c;
-  mp_int        t;
-  unsigned long r;
+   mp_err        err;
+   mp_digit      c;
+   mp_int        t;
+   unsigned long r;
 
-  /* Default to Non-square :) */
-  *ret = MP_NO; 
+   /* Default to Non-square :) */
+   *ret = MP_NO;
 
-  if (arg->sign == MP_NEG) {
-    return MP_VAL;
-  }
+   if (arg->sign == MP_NEG) {
+      return MP_VAL;
+   }
 
-  /* digits used?  (TSD) */
-  if (arg->used == 0) {
-     return MP_OKAY;
-  }
+   if (MP_IS_ZERO(arg)) {
+      return MP_OKAY;
+   }
 
-  /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
-  if (rem_128[127 & DIGIT(arg,0)] == 1) {
-     return MP_OKAY;
-  }
+   /* First check mod 128 (suppose that MP_DIGIT_BIT is at least 7) */
+   if (rem_128[127u & arg->dp[0]] == (char)1) {
+      return MP_OKAY;
+   }
 
-  /* Next check mod 105 (3*5*7) */
-  if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
-     return res;
-  }
-  if (rem_105[c] == 1) {
-     return MP_OKAY;
-  }
+   /* Next check mod 105 (3*5*7) */
+   if ((err = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) {
+      return err;
+   }
+   if (rem_105[c] == (char)1) {
+      return MP_OKAY;
+   }
 
 
-  if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
-     return res;
-  }
-  if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
-     goto ERR;
-  }
-  r = mp_get_int(&t);
-  /* Check for other prime modules, note it's not an ERROR but we must
-   * free "t" so the easiest way is to goto ERR.  We know that res
-   * is already equal to MP_OKAY from the mp_mod call 
-   */ 
-  if (((1L<<(r%11)) & 0x5C4L) != 0L)       goto ERR;
-  if (((1L<<(r%13)) & 0x9E4L) != 0L)       goto ERR;
-  if (((1L<<(r%17)) & 0x5CE8L) != 0L)      goto ERR;
-  if (((1L<<(r%19)) & 0x4F50CL) != 0L)     goto ERR;
-  if (((1L<<(r%23)) & 0x7ACCA0L) != 0L)    goto ERR;
-  if (((1L<<(r%29)) & 0xC2EDD0CL) != 0L)   goto ERR;
-  if (((1L<<(r%31)) & 0x6DE2B848L) != 0L)  goto ERR;
+   if ((err = mp_init_u32(&t, 11u*13u*17u*19u*23u*29u*31u)) != MP_OKAY) {
+      return err;
+   }
+   if ((err = mp_mod(arg, &t, &t)) != MP_OKAY) {
+      goto LBL_ERR;
+   }
+   r = mp_get_u32(&t);
+   /* Check for other prime modules, note it's not an ERROR but we must
+    * free "t" so the easiest way is to goto LBL_ERR.  We know that err
+    * is already equal to MP_OKAY from the mp_mod call
+    */
+   if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL)         goto LBL_ERR;
+   if (((1uL<<(r%13uL)) & 0x9E4uL) != 0uL)         goto LBL_ERR;
+   if (((1uL<<(r%17uL)) & 0x5CE8uL) != 0uL)        goto LBL_ERR;
+   if (((1uL<<(r%19uL)) & 0x4F50CuL) != 0uL)       goto LBL_ERR;
+   if (((1uL<<(r%23uL)) & 0x7ACCA0uL) != 0uL)      goto LBL_ERR;
+   if (((1uL<<(r%29uL)) & 0xC2EDD0CuL) != 0uL)     goto LBL_ERR;
+   if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL)    goto LBL_ERR;
 
-  /* Final check - is sqr(sqrt(arg)) == arg ? */
-  if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
-     goto ERR;
-  }
-  if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
-     goto ERR;
-  }
+   /* Final check - is sqr(sqrt(arg)) == arg ? */
+   if ((err = mp_sqrt(arg, &t)) != MP_OKAY) {
+      goto LBL_ERR;
+   }
+   if ((err = mp_sqr(&t, &t)) != MP_OKAY) {
+      goto LBL_ERR;
+   }
 
-  *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
-ERR:mp_clear(&t);
-  return res;
+   *ret = (mp_cmp_mag(&t, arg) == MP_EQ) ? MP_YES : MP_NO;
+LBL_ERR:
+   mp_clear(&t);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_iseven.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,10 @@
+#include "tommath_private.h"
+#ifdef BN_MP_ISEVEN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+mp_bool mp_iseven(const mp_int *a)
+{
+   return MP_IS_EVEN(a) ? MP_YES : MP_NO;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_isodd.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,10 @@
+#include "tommath_private.h"
+#ifdef BN_MP_ISODD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+mp_bool mp_isodd(const mp_int *a)
+{
+   return MP_IS_ODD(a) ? MP_YES : MP_NO;
+}
+#endif
--- a/libtommath/bn_mp_jacobi.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_JACOBI_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* computes the jacobi c = (a | n) (or Legendre if n is prime)
- * HAC pp. 73 Algorithm 2.149
- * HAC is wrong here, as the special case of (0 | 1) is not
- * handled correctly.
- */
-int mp_jacobi (mp_int * a, mp_int * n, int *c)
-{
-  mp_int  a1, p1;
-  int     k, s, r, res;
-  mp_digit residue;
-
-  /* if a < 0 return MP_VAL */
-  if (mp_isneg(a) == MP_YES) {
-     return MP_VAL;
-  }
-
-  /* if n <= 0 return MP_VAL */
-  if (mp_cmp_d(n, 0) != MP_GT) {
-     return MP_VAL;
-  }
-
-  /* step 1. handle case of a == 0 */
-  if (mp_iszero (a) == MP_YES) {
-     /* special case of a == 0 and n == 1 */
-     if (mp_cmp_d (n, 1) == MP_EQ) {
-       *c = 1;
-     } else {
-       *c = 0;
-     }
-     return MP_OKAY;
-  }
-
-  /* step 2.  if a == 1, return 1 */
-  if (mp_cmp_d (a, 1) == MP_EQ) {
-    *c = 1;
-    return MP_OKAY;
-  }
-
-  /* default */
-  s = 0;
-
-  /* step 3.  write a = a1 * 2**k  */
-  if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
-    return res;
-  }
-
-  if ((res = mp_init (&p1)) != MP_OKAY) {
-    goto LBL_A1;
-  }
-
-  /* divide out larger power of two */
-  k = mp_cnt_lsb(&a1);
-  if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
-     goto LBL_P1;
-  }
-
-  /* step 4.  if e is even set s=1 */
-  if ((k & 1) == 0) {
-    s = 1;
-  } else {
-    /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
-    residue = n->dp[0] & 7;
-
-    if ((residue == 1) || (residue == 7)) {
-      s = 1;
-    } else if ((residue == 3) || (residue == 5)) {
-      s = -1;
-    }
-  }
-
-  /* step 5.  if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
-  if ( ((n->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
-    s = -s;
-  }
-
-  /* if a1 == 1 we're done */
-  if (mp_cmp_d (&a1, 1) == MP_EQ) {
-    *c = s;
-  } else {
-    /* n1 = n mod a1 */
-    if ((res = mp_mod (n, &a1, &p1)) != MP_OKAY) {
-      goto LBL_P1;
-    }
-    if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
-      goto LBL_P1;
-    }
-    *c = s * r;
-  }
-
-  /* done */
-  res = MP_OKAY;
-LBL_P1:mp_clear (&p1);
-LBL_A1:mp_clear (&a1);
-  return res;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_karatsuba_mul.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_KARATSUBA_MUL_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* c = |a| * |b| using Karatsuba Multiplication using 
- * three half size multiplications
- *
- * Let B represent the radix [e.g. 2**DIGIT_BIT] and 
- * let n represent half of the number of digits in 
- * the min(a,b)
- *
- * a = a1 * B**n + a0
- * b = b1 * B**n + b0
- *
- * Then, a * b => 
-   a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
- *
- * Note that a1b1 and a0b0 are used twice and only need to be 
- * computed once.  So in total three half size (half # of 
- * digit) multiplications are performed, a0b0, a1b1 and 
- * (a1+b1)(a0+b0)
- *
- * Note that a multiplication of half the digits requires
- * 1/4th the number of single precision multiplications so in 
- * total after one call 25% of the single precision multiplications 
- * are saved.  Note also that the call to mp_mul can end up back 
- * in this function if the a0, a1, b0, or b1 are above the threshold.  
- * This is known as divide-and-conquer and leads to the famous 
- * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than 
- * the standard O(N**2) that the baseline/comba methods use.  
- * Generally though the overhead of this method doesn't pay off 
- * until a certain size (N ~ 80) is reached.
- */
-int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
-{
-  mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
-  int     B, err;
-
-  /* default the return code to an error */
-  err = MP_MEM;
-
-  /* min # of digits */
-  B = MIN (a->used, b->used);
-
-  /* now divide in two */
-  B = B >> 1;
-
-  /* init copy all the temps */
-  if (mp_init_size (&x0, B) != MP_OKAY)
-    goto ERR;
-  if (mp_init_size (&x1, a->used - B) != MP_OKAY)
-    goto X0;
-  if (mp_init_size (&y0, B) != MP_OKAY)
-    goto X1;
-  if (mp_init_size (&y1, b->used - B) != MP_OKAY)
-    goto Y0;
-
-  /* init temps */
-  if (mp_init_size (&t1, B * 2) != MP_OKAY)
-    goto Y1;
-  if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
-    goto T1;
-  if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
-    goto X0Y0;
-
-  /* now shift the digits */
-  x0.used = y0.used = B;
-  x1.used = a->used - B;
-  y1.used = b->used - B;
-
-  {
-    int x;
-    mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
-
-    /* we copy the digits directly instead of using higher level functions
-     * since we also need to shift the digits
-     */
-    tmpa = a->dp;
-    tmpb = b->dp;
-
-    tmpx = x0.dp;
-    tmpy = y0.dp;
-    for (x = 0; x < B; x++) {
-      *tmpx++ = *tmpa++;
-      *tmpy++ = *tmpb++;
-    }
-
-    tmpx = x1.dp;
-    for (x = B; x < a->used; x++) {
-      *tmpx++ = *tmpa++;
-    }
-
-    tmpy = y1.dp;
-    for (x = B; x < b->used; x++) {
-      *tmpy++ = *tmpb++;
-    }
-  }
-
-  /* only need to clamp the lower words since by definition the 
-   * upper words x1/y1 must have a known number of digits
-   */
-  mp_clamp (&x0);
-  mp_clamp (&y0);
-
-  /* now calc the products x0y0 and x1y1 */
-  /* after this x0 is no longer required, free temp [x0==t2]! */
-  if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)  
-    goto X1Y1;          /* x0y0 = x0*y0 */
-  if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
-    goto X1Y1;          /* x1y1 = x1*y1 */
-
-  /* now calc x1+x0 and y1+y0 */
-  if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
-    goto X1Y1;          /* t1 = x1 - x0 */
-  if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
-    goto X1Y1;          /* t2 = y1 - y0 */
-  if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
-    goto X1Y1;          /* t1 = (x1 + x0) * (y1 + y0) */
-
-  /* add x0y0 */
-  if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
-    goto X1Y1;          /* t2 = x0y0 + x1y1 */
-  if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
-    goto X1Y1;          /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
-
-  /* shift by B */
-  if (mp_lshd (&t1, B) != MP_OKAY)
-    goto X1Y1;          /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
-  if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
-    goto X1Y1;          /* x1y1 = x1y1 << 2*B */
-
-  if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
-    goto X1Y1;          /* t1 = x0y0 + t1 */
-  if (mp_add (&t1, &x1y1, c) != MP_OKAY)
-    goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
-
-  /* Algorithm succeeded set the return code to MP_OKAY */
-  err = MP_OKAY;
-
-X1Y1:mp_clear (&x1y1);
-X0Y0:mp_clear (&x0y0);
-T1:mp_clear (&t1);
-Y1:mp_clear (&y1);
-Y0:mp_clear (&y0);
-X1:mp_clear (&x1);
-X0:mp_clear (&x0);
-ERR:
-  return err;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_karatsuba_sqr.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_KARATSUBA_SQR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* Karatsuba squaring, computes b = a*a using three 
- * half size squarings
- *
- * See comments of karatsuba_mul for details.  It 
- * is essentially the same algorithm but merely 
- * tuned to perform recursive squarings.
- */
-int mp_karatsuba_sqr (mp_int * a, mp_int * b)
-{
-  mp_int  x0, x1, t1, t2, x0x0, x1x1;
-  int     B, err;
-
-  err = MP_MEM;
-
-  /* min # of digits */
-  B = a->used;
-
-  /* now divide in two */
-  B = B >> 1;
-
-  /* init copy all the temps */
-  if (mp_init_size (&x0, B) != MP_OKAY)
-    goto ERR;
-  if (mp_init_size (&x1, a->used - B) != MP_OKAY)
-    goto X0;
-
-  /* init temps */
-  if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
-    goto X1;
-  if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
-    goto T1;
-  if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
-    goto T2;
-  if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
-    goto X0X0;
-
-  {
-    int x;
-    mp_digit *dst, *src;
-
-    src = a->dp;
-
-    /* now shift the digits */
-    dst = x0.dp;
-    for (x = 0; x < B; x++) {
-      *dst++ = *src++;
-    }
-
-    dst = x1.dp;
-    for (x = B; x < a->used; x++) {
-      *dst++ = *src++;
-    }
-  }
-
-  x0.used = B;
-  x1.used = a->used - B;
-
-  mp_clamp (&x0);
-
-  /* now calc the products x0*x0 and x1*x1 */
-  if (mp_sqr (&x0, &x0x0) != MP_OKAY)
-    goto X1X1;           /* x0x0 = x0*x0 */
-  if (mp_sqr (&x1, &x1x1) != MP_OKAY)
-    goto X1X1;           /* x1x1 = x1*x1 */
-
-  /* now calc (x1+x0)**2 */
-  if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
-    goto X1X1;           /* t1 = x1 - x0 */
-  if (mp_sqr (&t1, &t1) != MP_OKAY)
-    goto X1X1;           /* t1 = (x1 - x0) * (x1 - x0) */
-
-  /* add x0y0 */
-  if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
-    goto X1X1;           /* t2 = x0x0 + x1x1 */
-  if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
-    goto X1X1;           /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
-
-  /* shift by B */
-  if (mp_lshd (&t1, B) != MP_OKAY)
-    goto X1X1;           /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
-  if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
-    goto X1X1;           /* x1x1 = x1x1 << 2*B */
-
-  if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
-    goto X1X1;           /* t1 = x0x0 + t1 */
-  if (mp_add (&t1, &x1x1, b) != MP_OKAY)
-    goto X1X1;           /* t1 = x0x0 + t1 + x1x1 */
-
-  err = MP_OKAY;
-
-X1X1:mp_clear (&x1x1);
-X0X0:mp_clear (&x0x0);
-T2:mp_clear (&t2);
-T1:mp_clear (&t1);
-X1:mp_clear (&x1);
-X0:mp_clear (&x0);
-ERR:
-  return err;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_kronecker.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,129 @@
+#include "tommath_private.h"
+#ifdef BN_MP_KRONECKER_C
+
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/*
+   Kronecker symbol (a|p)
+   Straightforward implementation of algorithm 1.4.10 in
+   Henri Cohen: "A Course in Computational Algebraic Number Theory"
+
+   @book{cohen2013course,
+     title={A course in computational algebraic number theory},
+     author={Cohen, Henri},
+     volume={138},
+     year={2013},
+     publisher={Springer Science \& Business Media}
+    }
+ */
+mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c)
+{
+   mp_int a1, p1, r;
+   mp_err err;
+   int v, k;
+
+   static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1};
+
+   if (MP_IS_ZERO(p)) {
+      if ((a->used == 1) && (a->dp[0] == 1u)) {
+         *c = 1;
+      } else {
+         *c = 0;
+      }
+      return MP_OKAY;
+   }
+
+   if (MP_IS_EVEN(a) && MP_IS_EVEN(p)) {
+      *c = 0;
+      return MP_OKAY;
+   }
+
+   if ((err = mp_init_copy(&a1, a)) != MP_OKAY) {
+      return err;
+   }
+   if ((err = mp_init_copy(&p1, p)) != MP_OKAY) {
+      goto LBL_KRON_0;
+   }
+
+   v = mp_cnt_lsb(&p1);
+   if ((err = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) {
+      goto LBL_KRON_1;
+   }
+
+   if ((v & 1) == 0) {
+      k = 1;
+   } else {
+      k = table[a->dp[0] & 7u];
+   }
+
+   if (p1.sign == MP_NEG) {
+      p1.sign = MP_ZPOS;
+      if (a1.sign == MP_NEG) {
+         k = -k;
+      }
+   }
+
+   if ((err = mp_init(&r)) != MP_OKAY) {
+      goto LBL_KRON_1;
+   }
+
+   for (;;) {
+      if (MP_IS_ZERO(&a1)) {
+         if (mp_cmp_d(&p1, 1uL) == MP_EQ) {
+            *c = k;
+            goto LBL_KRON;
+         } else {
+            *c = 0;
+            goto LBL_KRON;
+         }
+      }
+
+      v = mp_cnt_lsb(&a1);
+      if ((err = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) {
+         goto LBL_KRON;
+      }
+
+      if ((v & 1) == 1) {
+         k = k * table[p1.dp[0] & 7u];
+      }
+
+      if (a1.sign == MP_NEG) {
+         /*
+          * Compute k = (-1)^((a1)*(p1-1)/4) * k
+          * a1.dp[0] + 1 cannot overflow because the MSB
+          * of the type mp_digit is not set by definition
+          */
+         if (((a1.dp[0] + 1u) & p1.dp[0] & 2u) != 0u) {
+            k = -k;
+         }
+      } else {
+         /* compute k = (-1)^((a1-1)*(p1-1)/4) * k */
+         if ((a1.dp[0] & p1.dp[0] & 2u) != 0u) {
+            k = -k;
+         }
+      }
+
+      if ((err = mp_copy(&a1, &r)) != MP_OKAY) {
+         goto LBL_KRON;
+      }
+      r.sign = MP_ZPOS;
+      if ((err = mp_mod(&p1, &r, &a1)) != MP_OKAY) {
+         goto LBL_KRON;
+      }
+      if ((err = mp_copy(&r, &p1)) != MP_OKAY) {
+         goto LBL_KRON;
+      }
+   }
+
+LBL_KRON:
+   mp_clear(&r);
+LBL_KRON_1:
+   mp_clear(&p1);
+LBL_KRON_0:
+   mp_clear(&a1);
+
+   return err;
+}
+
+#endif
--- a/libtommath/bn_mp_lcm.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_lcm.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,60 +1,44 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_LCM_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* computes least common multiple as |a*b|/(a, b) */
-int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  int     res;
-  mp_int  t1, t2;
+   mp_err  err;
+   mp_int  t1, t2;
 
 
-  if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
-    return res;
-  }
+   if ((err = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) {
+      return err;
+   }
 
-  /* t1 = get the GCD of the two inputs */
-  if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
-    goto LBL_T;
-  }
+   /* t1 = get the GCD of the two inputs */
+   if ((err = mp_gcd(a, b, &t1)) != MP_OKAY) {
+      goto LBL_T;
+   }
 
-  /* divide the smallest by the GCD */
-  if (mp_cmp_mag(a, b) == MP_LT) {
-     /* store quotient in t2 such that t2 * b is the LCM */
-     if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
-        goto LBL_T;
-     }
-     res = mp_mul(b, &t2, c);
-  } else {
-     /* store quotient in t2 such that t2 * a is the LCM */
-     if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
-        goto LBL_T;
-     }
-     res = mp_mul(a, &t2, c);
-  }
+   /* divide the smallest by the GCD */
+   if (mp_cmp_mag(a, b) == MP_LT) {
+      /* store quotient in t2 such that t2 * b is the LCM */
+      if ((err = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
+         goto LBL_T;
+      }
+      err = mp_mul(b, &t2, c);
+   } else {
+      /* store quotient in t2 such that t2 * a is the LCM */
+      if ((err = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
+         goto LBL_T;
+      }
+      err = mp_mul(a, &t2, c);
+   }
 
-  /* fix the sign to positive */
-  c->sign = MP_ZPOS;
+   /* fix the sign to positive */
+   c->sign = MP_ZPOS;
 
 LBL_T:
-  mp_clear_multi (&t1, &t2, NULL);
-  return res;
+   mp_clear_multi(&t1, &t2, NULL);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_log_u32.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,180 @@
+#include "tommath_private.h"
+#ifdef BN_MP_LOG_U32_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* Compute log_{base}(a) */
+static mp_word s_pow(mp_word base, mp_word exponent)
+{
+   mp_word result = 1uLL;
+   while (exponent != 0u) {
+      if ((exponent & 1u) == 1u) {
+         result *= base;
+      }
+      exponent >>= 1;
+      base *= base;
+   }
+
+   return result;
+}
+
+static mp_digit s_digit_ilogb(mp_digit base, mp_digit n)
+{
+   mp_word bracket_low = 1uLL, bracket_mid, bracket_high, N;
+   mp_digit ret, high = 1uL, low = 0uL, mid;
+
+   if (n < base) {
+      return 0uL;
+   }
+   if (n == base) {
+      return 1uL;
+   }
+
+   bracket_high = (mp_word) base ;
+   N = (mp_word) n;
+
+   while (bracket_high < N) {
+      low = high;
+      bracket_low = bracket_high;
+      high <<= 1;
+      bracket_high *= bracket_high;
+   }
+
+   while (((mp_digit)(high - low)) > 1uL) {
+      mid = (low + high) >> 1;
+      bracket_mid = bracket_low * s_pow(base, (mp_word)(mid - low));
+
+      if (N < bracket_mid) {
+         high = mid ;
+         bracket_high = bracket_mid ;
+      }
+      if (N > bracket_mid) {
+         low = mid ;
+         bracket_low = bracket_mid ;
+      }
+      if (N == bracket_mid) {
+         return (mp_digit) mid;
+      }
+   }
+
+   if (bracket_high == N) {
+      ret = high;
+   } else {
+      ret = low;
+   }
+
+   return ret;
+}
+
+/* TODO: output could be "int" because the output of mp_radix_size is int, too,
+         as is the output of mp_bitcount.
+         With the same problem: max size is INT_MAX * MP_DIGIT not INT_MAX only!
+*/
+mp_err mp_log_u32(const mp_int *a, uint32_t base, uint32_t *c)
+{
+   mp_err err;
+   mp_ord cmp;
+   uint32_t high, low, mid;
+   mp_int bracket_low, bracket_high, bracket_mid, t, bi_base;
+
+   err = MP_OKAY;
+
+   if (a->sign == MP_NEG) {
+      return MP_VAL;
+   }
+
+   if (MP_IS_ZERO(a)) {
+      return MP_VAL;
+   }
+
+   if (base < 2u) {
+      return MP_VAL;
+   }
+
+   /* A small shortcut for bases that are powers of two. */
+   if ((base & (base - 1u)) == 0u) {
+      int y, bit_count;
+      for (y=0; (y < 7) && ((base & 1u) == 0u); y++) {
+         base >>= 1;
+      }
+      bit_count = mp_count_bits(a) - 1;
+      *c = (uint32_t)(bit_count/y);
+      return MP_OKAY;
+   }
+
+   if (a->used == 1) {
+      *c = (uint32_t)s_digit_ilogb(base, a->dp[0]);
+      return err;
+   }
+
+   cmp = mp_cmp_d(a, base);
+   if ((cmp == MP_LT) || (cmp == MP_EQ)) {
+      *c = cmp == MP_EQ;
+      return err;
+   }
+
+   if ((err =
+           mp_init_multi(&bracket_low, &bracket_high,
+                         &bracket_mid, &t, &bi_base, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   low = 0u;
+   mp_set(&bracket_low, 1uL);
+   high = 1u;
+
+   mp_set(&bracket_high, base);
+
+   /*
+       A kind of Giant-step/baby-step algorithm.
+       Idea shamelessly stolen from https://programmingpraxis.com/2010/05/07/integer-logarithms/2/
+       The effect is asymptotic, hence needs benchmarks to test if the Giant-step should be skipped
+       for small n.
+    */
+   while (mp_cmp(&bracket_high, a) == MP_LT) {
+      low = high;
+      if ((err = mp_copy(&bracket_high, &bracket_low)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      high <<= 1;
+      if ((err = mp_sqr(&bracket_high, &bracket_high)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+   }
+   mp_set(&bi_base, base);
+
+   while ((high - low) > 1u) {
+      mid = (high + low) >> 1;
+
+      if ((err = mp_expt_u32(&bi_base, (uint32_t)(mid - low), &t)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((err = mp_mul(&bracket_low, &t, &bracket_mid)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      cmp = mp_cmp(a, &bracket_mid);
+      if (cmp == MP_LT) {
+         high = mid;
+         mp_exch(&bracket_mid, &bracket_high);
+      }
+      if (cmp == MP_GT) {
+         low = mid;
+         mp_exch(&bracket_mid, &bracket_low);
+      }
+      if (cmp == MP_EQ) {
+         *c = mid;
+         goto LBL_END;
+      }
+   }
+
+   *c = (mp_cmp(&bracket_high, a) == MP_EQ) ? high : low;
+
+LBL_END:
+LBL_ERR:
+   mp_clear_multi(&bracket_low, &bracket_high, &bracket_mid,
+                  &t, &bi_base, NULL);
+   return err;
+}
+
+
+#endif
--- a/libtommath/bn_mp_lshd.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_lshd.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,67 +1,51 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_LSHD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* shift left a certain amount of digits */
-int mp_lshd (mp_int * a, int b)
+mp_err mp_lshd(mp_int *a, int b)
 {
-  int     x, res;
-
-  /* if its less than zero return */
-  if (b <= 0) {
-    return MP_OKAY;
-  }
+   int x;
+   mp_err err;
+   mp_digit *top, *bottom;
 
-  /* grow to fit the new digits */
-  if (a->alloc < (a->used + b)) {
-     if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
-       return res;
-     }
-  }
+   /* if its less than zero return */
+   if (b <= 0) {
+      return MP_OKAY;
+   }
+   /* no need to shift 0 around */
+   if (MP_IS_ZERO(a)) {
+      return MP_OKAY;
+   }
 
-  {
-    mp_digit *top, *bottom;
-
-    /* increment the used by the shift amount then copy upwards */
-    a->used += b;
+   /* grow to fit the new digits */
+   if (a->alloc < (a->used + b)) {
+      if ((err = mp_grow(a, a->used + b)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-    /* top */
-    top = a->dp + a->used - 1;
+   /* increment the used by the shift amount then copy upwards */
+   a->used += b;
 
-    /* base */
-    bottom = (a->dp + a->used - 1) - b;
+   /* top */
+   top = a->dp + a->used - 1;
+
+   /* base */
+   bottom = (a->dp + a->used - 1) - b;
 
-    /* much like mp_rshd this is implemented using a sliding window
-     * except the window goes the otherway around.  Copying from
-     * the bottom to the top.  see bn_mp_rshd.c for more info.
-     */
-    for (x = a->used - 1; x >= b; x--) {
+   /* much like mp_rshd this is implemented using a sliding window
+    * except the window goes the otherway around.  Copying from
+    * the bottom to the top.  see bn_mp_rshd.c for more info.
+    */
+   for (x = a->used - 1; x >= b; x--) {
       *top-- = *bottom--;
-    }
+   }
 
-    /* zero the lower digits */
-    top = a->dp;
-    for (x = 0; x < b; x++) {
-      *top++ = 0;
-    }
-  }
-  return MP_OKAY;
+   /* zero the lower digits */
+   MP_ZERO_DIGITS(a->dp, b);
+
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mod.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mod.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,48 +1,31 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */
-int
-mp_mod (mp_int * a, mp_int * b, mp_int * c)
+mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  mp_int  t;
-  int     res;
+   mp_int  t;
+   mp_err  err;
 
-  if ((res = mp_init_size (&t, b->used)) != MP_OKAY) {
-    return res;
-  }
+   if ((err = mp_init_size(&t, b->used)) != MP_OKAY) {
+      return err;
+   }
 
-  if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
-    mp_clear (&t);
-    return res;
-  }
+   if ((err = mp_div(a, b, NULL, &t)) != MP_OKAY) {
+      goto LBL_ERR;
+   }
 
-  if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) {
-    res = MP_OKAY;
-    mp_exch (&t, c);
-  } else {
-    res = mp_add (b, &t, c);
-  }
+   if (MP_IS_ZERO(&t) || (t.sign == b->sign)) {
+      err = MP_OKAY;
+      mp_exch(&t, c);
+   } else {
+      err = mp_add(b, &t, c);
+   }
 
-  mp_clear (&t);
-  return res;
+LBL_ERR:
+   mp_clear(&t);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mod_2d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mod_2d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,55 +1,38 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MOD_2D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* calc a value mod 2**b */
-int
-mp_mod_2d (mp_int * a, int b, mp_int * c)
+mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c)
 {
-  int     x, res;
+   int x;
+   mp_err err;
 
-  /* if b is <= 0 then zero the int */
-  if (b <= 0) {
-    mp_zero (c);
-    return MP_OKAY;
-  }
+   /* if b is <= 0 then zero the int */
+   if (b <= 0) {
+      mp_zero(c);
+      return MP_OKAY;
+   }
 
-  /* if the modulus is larger than the value than return */
-  if (b >= (int) (a->used * DIGIT_BIT)) {
-    res = mp_copy (a, c);
-    return res;
-  }
+   /* if the modulus is larger than the value than return */
+   if (b >= (a->used * MP_DIGIT_BIT)) {
+      return mp_copy(a, c);
+   }
+
+   /* copy */
+   if ((err = mp_copy(a, c)) != MP_OKAY) {
+      return err;
+   }
 
-  /* copy */
-  if ((res = mp_copy (a, c)) != MP_OKAY) {
-    return res;
-  }
+   /* zero digits above the last digit of the modulus */
+   x = (b / MP_DIGIT_BIT) + (((b % MP_DIGIT_BIT) == 0) ? 0 : 1);
+   MP_ZERO_DIGITS(c->dp + x, c->used - x);
 
-  /* zero digits above the last digit of the modulus */
-  for (x = (b / DIGIT_BIT) + (((b % DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) {
-    c->dp[x] = 0;
-  }
-  /* clear the digit that is not completely outside/inside the modulus */
-  c->dp[b / DIGIT_BIT] &=
-    (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
-  mp_clamp (c);
-  return MP_OKAY;
+   /* clear the digit that is not completely outside/inside the modulus */
+   c->dp[b / MP_DIGIT_BIT] &=
+      ((mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT)) - (mp_digit)1;
+   mp_clamp(c);
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mod_d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mod_d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,27 +1,10 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MOD_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-int
-mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
+mp_err mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c)
 {
-  return mp_div_d(a, b, NULL, c);
+   return mp_div_d(a, b, NULL, c);
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_montgomery_calc_normalization.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_montgomery_calc_normalization.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,19 +1,7 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /*
  * shifts with subtractions when the result is greater than b.
@@ -21,39 +9,36 @@
  * The method is slightly modified to shift B unconditionally upto just under
  * the leading bit of b.  This saves alot of multiple precision shifting.
  */
-int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
+mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b)
 {
-  int     x, bits, res;
+   int    x, bits;
+   mp_err err;
 
-  /* how many bits of last digit does b use */
-  bits = mp_count_bits (b) % DIGIT_BIT;
+   /* how many bits of last digit does b use */
+   bits = mp_count_bits(b) % MP_DIGIT_BIT;
 
-  if (b->used > 1) {
-     if ((res = mp_2expt (a, ((b->used - 1) * DIGIT_BIT) + bits - 1)) != MP_OKAY) {
-        return res;
-     }
-  } else {
-     mp_set(a, 1);
-     bits = 1;
-  }
+   if (b->used > 1) {
+      if ((err = mp_2expt(a, ((b->used - 1) * MP_DIGIT_BIT) + bits - 1)) != MP_OKAY) {
+         return err;
+      }
+   } else {
+      mp_set(a, 1uL);
+      bits = 1;
+   }
 
 
-  /* now compute C = A * B mod b */
-  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
-    if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
-      return res;
-    }
-    if (mp_cmp_mag (a, b) != MP_LT) {
-      if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
-        return res;
+   /* now compute C = A * B mod b */
+   for (x = bits - 1; x < (int)MP_DIGIT_BIT; x++) {
+      if ((err = mp_mul_2(a, a)) != MP_OKAY) {
+         return err;
       }
-    }
-  }
+      if (mp_cmp_mag(a, b) != MP_LT) {
+         if ((err = s_mp_sub(a, b, a)) != MP_OKAY) {
+            return err;
+         }
+      }
+   }
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_montgomery_reduce.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_montgomery_reduce.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,118 +1,102 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MONTGOMERY_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* computes xR**-1 == x (mod N) via Montgomery Reduction */
-int
-mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
 {
-  int     ix, res, digs;
-  mp_digit mu;
+   int      ix, digs;
+   mp_err   err;
+   mp_digit mu;
 
-  /* can the fast reduction [comba] method be used?
-   *
-   * Note that unlike in mul you're safely allowed *less*
-   * than the available columns [255 per default] since carries
-   * are fixed up in the inner loop.
-   */
-  digs = (n->used * 2) + 1;
-  if ((digs < MP_WARRAY) &&
-      (n->used <
-      (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
-    return fast_mp_montgomery_reduce (x, n, rho);
-  }
+   /* can the fast reduction [comba] method be used?
+    *
+    * Note that unlike in mul you're safely allowed *less*
+    * than the available columns [255 per default] since carries
+    * are fixed up in the inner loop.
+    */
+   digs = (n->used * 2) + 1;
+   if ((digs < MP_WARRAY) &&
+       (x->used <= MP_WARRAY) &&
+       (n->used < MP_MAXFAST)) {
+      return s_mp_montgomery_reduce_fast(x, n, rho);
+   }
 
-  /* grow the input as required */
-  if (x->alloc < digs) {
-    if ((res = mp_grow (x, digs)) != MP_OKAY) {
-      return res;
-    }
-  }
-  x->used = digs;
+   /* grow the input as required */
+   if (x->alloc < digs) {
+      if ((err = mp_grow(x, digs)) != MP_OKAY) {
+         return err;
+      }
+   }
+   x->used = digs;
 
-  for (ix = 0; ix < n->used; ix++) {
-    /* mu = ai * rho mod b
-     *
-     * The value of rho must be precalculated via
-     * montgomery_setup() such that
-     * it equals -1/n0 mod b this allows the
-     * following inner loop to reduce the
-     * input one digit at a time
-     */
-    mu = (mp_digit) (((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK);
+   for (ix = 0; ix < n->used; ix++) {
+      /* mu = ai * rho mod b
+       *
+       * The value of rho must be precalculated via
+       * montgomery_setup() such that
+       * it equals -1/n0 mod b this allows the
+       * following inner loop to reduce the
+       * input one digit at a time
+       */
+      mu = (mp_digit)(((mp_word)x->dp[ix] * (mp_word)rho) & MP_MASK);
 
-    /* a = a + mu * m * b**i */
-    {
-      int iy;
-      mp_digit *tmpn, *tmpx, u;
-      mp_word r;
+      /* a = a + mu * m * b**i */
+      {
+         int iy;
+         mp_digit *tmpn, *tmpx, u;
+         mp_word r;
 
-      /* alias for digits of the modulus */
-      tmpn = n->dp;
+         /* alias for digits of the modulus */
+         tmpn = n->dp;
 
-      /* alias for the digits of x [the input] */
-      tmpx = x->dp + ix;
+         /* alias for the digits of x [the input] */
+         tmpx = x->dp + ix;
 
-      /* set the carry to zero */
-      u = 0;
+         /* set the carry to zero */
+         u = 0;
 
-      /* Multiply and add in place */
-      for (iy = 0; iy < n->used; iy++) {
-        /* compute product and sum */
-        r       = ((mp_word)mu * (mp_word)*tmpn++) +
-                   (mp_word) u + (mp_word) *tmpx;
+         /* Multiply and add in place */
+         for (iy = 0; iy < n->used; iy++) {
+            /* compute product and sum */
+            r       = ((mp_word)mu * (mp_word)*tmpn++) +
+                      (mp_word)u + (mp_word)*tmpx;
 
-        /* get carry */
-        u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+            /* get carry */
+            u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
 
-        /* fix digit */
-        *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
-      }
-      /* At this point the ix'th digit of x should be zero */
+            /* fix digit */
+            *tmpx++ = (mp_digit)(r & (mp_word)MP_MASK);
+         }
+         /* At this point the ix'th digit of x should be zero */
 
 
-      /* propagate carries upwards as required*/
-      while (u != 0) {
-        *tmpx   += u;
-        u        = *tmpx >> DIGIT_BIT;
-        *tmpx++ &= MP_MASK;
+         /* propagate carries upwards as required*/
+         while (u != 0u) {
+            *tmpx   += u;
+            u        = *tmpx >> MP_DIGIT_BIT;
+            *tmpx++ &= MP_MASK;
+         }
       }
-    }
-  }
+   }
 
-  /* at this point the n.used'th least
-   * significant digits of x are all zero
-   * which means we can shift x to the
-   * right by n.used digits and the
-   * residue is unchanged.
-   */
+   /* at this point the n.used'th least
+    * significant digits of x are all zero
+    * which means we can shift x to the
+    * right by n.used digits and the
+    * residue is unchanged.
+    */
 
-  /* x = x/b**n.used */
-  mp_clamp(x);
-  mp_rshd (x, n->used);
+   /* x = x/b**n.used */
+   mp_clamp(x);
+   mp_rshd(x, n->used);
 
-  /* if x >= n then x = x - n */
-  if (mp_cmp_mag (x, n) != MP_LT) {
-    return s_mp_sub (x, n, x);
-  }
+   /* if x >= n then x = x - n */
+   if (mp_cmp_mag(x, n) != MP_LT) {
+      return s_mp_sub(x, n, x);
+   }
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_montgomery_setup.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_montgomery_setup.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,59 +1,42 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MONTGOMERY_SETUP_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* setups the montgomery reduction stuff */
-int
-mp_montgomery_setup (mp_int * n, mp_digit * rho)
+mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho)
 {
-  mp_digit x, b;
+   mp_digit x, b;
 
-/* fast inversion mod 2**k
- *
- * Based on the fact that
- *
- * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
- *                    =>  2*X*A - X*X*A*A = 1
- *                    =>  2*(1) - (1)     = 1
- */
-  b = n->dp[0];
+   /* fast inversion mod 2**k
+    *
+    * Based on the fact that
+    *
+    * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
+    *                    =>  2*X*A - X*X*A*A = 1
+    *                    =>  2*(1) - (1)     = 1
+    */
+   b = n->dp[0];
 
-  if ((b & 1) == 0) {
-    return MP_VAL;
-  }
+   if ((b & 1u) == 0u) {
+      return MP_VAL;
+   }
 
-  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
-  x *= 2 - (b * x);             /* here x*a==1 mod 2**8 */
+   x = (((b + 2u) & 4u) << 1) + b; /* here x*a==1 mod 2**4 */
+   x *= 2u - (b * x);              /* here x*a==1 mod 2**8 */
 #if !defined(MP_8BIT)
-  x *= 2 - (b * x);             /* here x*a==1 mod 2**16 */
+   x *= 2u - (b * x);              /* here x*a==1 mod 2**16 */
 #endif
 #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
-  x *= 2 - (b * x);             /* here x*a==1 mod 2**32 */
+   x *= 2u - (b * x);              /* here x*a==1 mod 2**32 */
 #endif
 #ifdef MP_64BIT
-  x *= 2 - (b * x);             /* here x*a==1 mod 2**64 */
+   x *= 2u - (b * x);              /* here x*a==1 mod 2**64 */
 #endif
 
-  /* rho = -1/m mod b */
-  *rho = (mp_digit)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
+   /* rho = -1/m mod b */
+   *rho = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - x) & MP_MASK;
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mul.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mul.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,67 +1,52 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MUL_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* high level multiplication (handles sign) */
-int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  int     res, neg;
-  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+   mp_err err;
+   int min_len = MP_MIN(a->used, b->used),
+       max_len = MP_MAX(a->used, b->used),
+       digs = a->used + b->used + 1;
+   mp_sign neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
 
-  /* use Toom-Cook? */
-#ifdef BN_MP_TOOM_MUL_C
-  if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
-    res = mp_toom_mul(a, b, c);
-  } else 
-#endif
-#ifdef BN_MP_KARATSUBA_MUL_C
-  /* use Karatsuba? */
-  if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
-    res = mp_karatsuba_mul (a, b, c);
-  } else 
-#endif
-  {
-    /* can we use the fast multiplier?
-     *
-     * The fast multiplier can be used if the output will 
-     * have less than MP_WARRAY digits and the number of 
-     * digits won't affect carry propagation
-     */
-    int     digs = a->used + b->used + 1;
-
-#ifdef BN_FAST_S_MP_MUL_DIGS_C
-    if ((digs < MP_WARRAY) &&
-        (MIN(a->used, b->used) <= 
-         (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
-      res = fast_s_mp_mul_digs (a, b, c, digs);
-    } else 
-#endif
-    {
-#ifdef BN_S_MP_MUL_DIGS_C
-      res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
-#else
-      res = MP_VAL;
-#endif
-    }
-  }
-  c->sign = (c->used > 0) ? neg : MP_ZPOS;
-  return res;
+   if (MP_HAS(S_MP_BALANCE_MUL) &&
+       /* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off.
+        * The bigger one needs to be at least about one MP_KARATSUBA_MUL_CUTOFF bigger
+        * to make some sense, but it depends on architecture, OS, position of the
+        * stars... so YMMV.
+        * Using it to cut the input into slices small enough for fast_s_mp_mul_digs
+        * was actually slower on the author's machine, but YMMV.
+        */
+       (min_len >= MP_KARATSUBA_MUL_CUTOFF) &&
+       ((max_len / 2) >= MP_KARATSUBA_MUL_CUTOFF) &&
+       /* Not much effect was observed below a ratio of 1:2, but again: YMMV. */
+       (max_len >= (2 * min_len))) {
+      err = s_mp_balance_mul(a,b,c);
+   } else if (MP_HAS(S_MP_TOOM_MUL) &&
+              (min_len >= MP_TOOM_MUL_CUTOFF)) {
+      err = s_mp_toom_mul(a, b, c);
+   } else if (MP_HAS(S_MP_KARATSUBA_MUL) &&
+              (min_len >= MP_KARATSUBA_MUL_CUTOFF)) {
+      err = s_mp_karatsuba_mul(a, b, c);
+   } else if (MP_HAS(S_MP_MUL_DIGS_FAST) &&
+              /* can we use the fast multiplier?
+               *
+               * The fast multiplier can be used if the output will
+               * have less than MP_WARRAY digits and the number of
+               * digits won't affect carry propagation
+               */
+              (digs < MP_WARRAY) &&
+              (min_len <= MP_MAXFAST)) {
+      err = s_mp_mul_digs_fast(a, b, c, digs);
+   } else if (MP_HAS(S_MP_MUL_DIGS)) {
+      err = s_mp_mul_digs(a, b, c, digs);
+   } else {
+      err = MP_VAL;
+   }
+   c->sign = (c->used > 0) ? neg : MP_ZPOS;
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mul_2.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mul_2.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,82 +1,64 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MUL_2_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* b = a*2 */
-int mp_mul_2(mp_int * a, mp_int * b)
+mp_err mp_mul_2(const mp_int *a, mp_int *b)
 {
-  int     x, res, oldused;
+   int     x, oldused;
+   mp_err err;
 
-  /* grow to accomodate result */
-  if (b->alloc < (a->used + 1)) {
-    if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
-      return res;
-    }
-  }
+   /* grow to accomodate result */
+   if (b->alloc < (a->used + 1)) {
+      if ((err = mp_grow(b, a->used + 1)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  oldused = b->used;
-  b->used = a->used;
+   oldused = b->used;
+   b->used = a->used;
 
-  {
-    mp_digit r, rr, *tmpa, *tmpb;
+   {
+      mp_digit r, rr, *tmpa, *tmpb;
 
-    /* alias for source */
-    tmpa = a->dp;
-    
-    /* alias for dest */
-    tmpb = b->dp;
+      /* alias for source */
+      tmpa = a->dp;
+
+      /* alias for dest */
+      tmpb = b->dp;
+
+      /* carry */
+      r = 0;
+      for (x = 0; x < a->used; x++) {
 
-    /* carry */
-    r = 0;
-    for (x = 0; x < a->used; x++) {
-    
-      /* get what will be the *next* carry bit from the 
-       * MSB of the current digit 
-       */
-      rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
-      
-      /* now shift up this digit, add in the carry [from the previous] */
-      *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
-      
-      /* copy the carry that would be from the source 
-       * digit into the next iteration 
-       */
-      r = rr;
-    }
+         /* get what will be the *next* carry bit from the
+          * MSB of the current digit
+          */
+         rr = *tmpa >> (mp_digit)(MP_DIGIT_BIT - 1);
+
+         /* now shift up this digit, add in the carry [from the previous] */
+         *tmpb++ = ((*tmpa++ << 1uL) | r) & MP_MASK;
+
+         /* copy the carry that would be from the source
+          * digit into the next iteration
+          */
+         r = rr;
+      }
 
-    /* new leading digit? */
-    if (r != 0) {
-      /* add a MSB which is always 1 at this point */
-      *tmpb = 1;
-      ++(b->used);
-    }
+      /* new leading digit? */
+      if (r != 0u) {
+         /* add a MSB which is always 1 at this point */
+         *tmpb = 1;
+         ++(b->used);
+      }
 
-    /* now zero any excess digits on the destination 
-     * that we didn't write to 
-     */
-    tmpb = b->dp + b->used;
-    for (x = b->used; x < oldused; x++) {
-      *tmpb++ = 0;
-    }
-  }
-  b->sign = a->sign;
-  return MP_OKAY;
+      /* now zero any excess digits on the destination
+       * that we didn't write to
+       */
+      MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
+   }
+   b->sign = a->sign;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mul_2d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mul_2d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,85 +1,69 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MUL_2D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* shift left by a certain bit count */
-int mp_mul_2d (mp_int * a, int b, mp_int * c)
+mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c)
 {
-  mp_digit d;
-  int      res;
+   mp_digit d;
+   mp_err   err;
 
-  /* copy */
-  if (a != c) {
-     if ((res = mp_copy (a, c)) != MP_OKAY) {
-       return res;
-     }
-  }
+   /* copy */
+   if (a != c) {
+      if ((err = mp_copy(a, c)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  if (c->alloc < (int)(c->used + (b / DIGIT_BIT) + 1)) {
-     if ((res = mp_grow (c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) {
-       return res;
-     }
-  }
+   if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) {
+      if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  /* shift by as many digits in the bit count */
-  if (b >= (int)DIGIT_BIT) {
-    if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
-      return res;
-    }
-  }
+   /* shift by as many digits in the bit count */
+   if (b >= MP_DIGIT_BIT) {
+      if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  /* shift any bit count < DIGIT_BIT */
-  d = (mp_digit) (b % DIGIT_BIT);
-  if (d != 0) {
-    mp_digit *tmpc, shift, mask, r, rr;
-    int x;
+   /* shift any bit count < MP_DIGIT_BIT */
+   d = (mp_digit)(b % MP_DIGIT_BIT);
+   if (d != 0u) {
+      mp_digit *tmpc, shift, mask, r, rr;
+      int x;
 
-    /* bitmask for carries */
-    mask = (((mp_digit)1) << d) - 1;
+      /* bitmask for carries */
+      mask = ((mp_digit)1 << d) - (mp_digit)1;
 
-    /* shift for msbs */
-    shift = DIGIT_BIT - d;
+      /* shift for msbs */
+      shift = (mp_digit)MP_DIGIT_BIT - d;
 
-    /* alias */
-    tmpc = c->dp;
+      /* alias */
+      tmpc = c->dp;
 
-    /* carry */
-    r    = 0;
-    for (x = 0; x < c->used; x++) {
-      /* get the higher bits of the current word */
-      rr = (*tmpc >> shift) & mask;
+      /* carry */
+      r    = 0;
+      for (x = 0; x < c->used; x++) {
+         /* get the higher bits of the current word */
+         rr = (*tmpc >> shift) & mask;
 
-      /* shift the current word and OR in the carry */
-      *tmpc = ((*tmpc << d) | r) & MP_MASK;
-      ++tmpc;
+         /* shift the current word and OR in the carry */
+         *tmpc = ((*tmpc << d) | r) & MP_MASK;
+         ++tmpc;
+
+         /* set the carry to the carry bits of the current word */
+         r = rr;
+      }
 
-      /* set the carry to the carry bits of the current word */
-      r = rr;
-    }
-    
-    /* set final carry */
-    if (r != 0) {
-       c->dp[(c->used)++] = r;
-    }
-  }
-  mp_clamp (c);
-  return MP_OKAY;
+      /* set final carry */
+      if (r != 0u) {
+         c->dp[(c->used)++] = r;
+      }
+   }
+   mp_clamp(c);
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mul_d.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mul_d.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,79 +1,61 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MUL_D_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* multiply by a digit */
-int
-mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c)
 {
-  mp_digit u, *tmpa, *tmpc;
-  mp_word  r;
-  int      ix, res, olduse;
+   mp_digit u, *tmpa, *tmpc;
+   mp_word  r;
+   mp_err   err;
+   int      ix, olduse;
 
-  /* make sure c is big enough to hold a*b */
-  if (c->alloc < (a->used + 1)) {
-    if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
-      return res;
-    }
-  }
+   /* make sure c is big enough to hold a*b */
+   if (c->alloc < (a->used + 1)) {
+      if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  /* get the original destinations used count */
-  olduse = c->used;
+   /* get the original destinations used count */
+   olduse = c->used;
 
-  /* set the sign */
-  c->sign = a->sign;
+   /* set the sign */
+   c->sign = a->sign;
 
-  /* alias for a->dp [source] */
-  tmpa = a->dp;
+   /* alias for a->dp [source] */
+   tmpa = a->dp;
 
-  /* alias for c->dp [dest] */
-  tmpc = c->dp;
+   /* alias for c->dp [dest] */
+   tmpc = c->dp;
 
-  /* zero carry */
-  u = 0;
+   /* zero carry */
+   u = 0;
 
-  /* compute columns */
-  for (ix = 0; ix < a->used; ix++) {
-    /* compute product and carry sum for this term */
-    r       = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b);
+   /* compute columns */
+   for (ix = 0; ix < a->used; ix++) {
+      /* compute product and carry sum for this term */
+      r       = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b);
 
-    /* mask off higher bits to get a single digit */
-    *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
-    /* send carry into next iteration */
-    u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
-  }
+      /* mask off higher bits to get a single digit */
+      *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK);
 
-  /* store final carry [if any] and increment ix offset  */
-  *tmpc++ = u;
-  ++ix;
+      /* send carry into next iteration */
+      u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
+   }
+
+   /* store final carry [if any] and increment ix offset  */
+   *tmpc++ = u;
+   ++ix;
 
-  /* now zero digits above the top */
-  while (ix++ < olduse) {
-     *tmpc++ = 0;
-  }
+   /* now zero digits above the top */
+   MP_ZERO_DIGITS(tmpc, olduse - ix);
 
-  /* set used count */
-  c->used = a->used + 1;
-  mp_clamp(c);
+   /* set used count */
+   c->used = a->used + 1;
+   mp_clamp(c);
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_mulmod.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_mulmod.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,40 +1,25 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_MULMOD_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* d = a * b (mod c) */
-int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
 {
-  int     res;
-  mp_int  t;
+   mp_err err;
+   mp_int t;
+
+   if ((err = mp_init_size(&t, c->used)) != MP_OKAY) {
+      return err;
+   }
 
-  if ((res = mp_init_size (&t, c->used)) != MP_OKAY) {
-    return res;
-  }
+   if ((err = mp_mul(a, b, &t)) != MP_OKAY) {
+      goto LBL_ERR;
+   }
+   err = mp_mod(&t, c, d);
 
-  if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
-    mp_clear (&t);
-    return res;
-  }
-  res = mp_mod (&t, c, d);
-  mp_clear (&t);
-  return res;
+LBL_ERR:
+   mp_clear(&t);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_n_root.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_N_ROOT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* wrapper function for mp_n_root_ex()
- * computes c = (a)**(1/b) such that (c)**b <= a and (c+1)**b > a
- */
-int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
-{
-  return mp_n_root_ex(a, b, c, 0);
-}
-
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_n_root_ex.c	Thu Mar 21 23:28:59 2019 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-#include <tommath_private.h>
-#ifdef BN_MP_N_ROOT_EX_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
-
-/* find the n'th root of an integer
- *
- * Result found such that (c)**b <= a and (c+1)**b > a
- *
- * This algorithm uses Newton's approximation
- * x[i+1] = x[i] - f(x[i])/f'(x[i])
- * which will find the root in log(N) time where
- * each step involves a fair bit.  This is not meant to
- * find huge roots [square and cube, etc].
- */
-int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast)
-{
-  mp_int  t1, t2, t3;
-  int     res, neg;
-
-  /* input must be positive if b is even */
-  if (((b & 1) == 0) && (a->sign == MP_NEG)) {
-    return MP_VAL;
-  }
-
-  if ((res = mp_init (&t1)) != MP_OKAY) {
-    return res;
-  }
-
-  if ((res = mp_init (&t2)) != MP_OKAY) {
-    goto LBL_T1;
-  }
-
-  if ((res = mp_init (&t3)) != MP_OKAY) {
-    goto LBL_T2;
-  }
-
-  /* if a is negative fudge the sign but keep track */
-  neg     = a->sign;
-  a->sign = MP_ZPOS;
-
-  /* t2 = 2 */
-  mp_set (&t2, 2);
-
-  do {
-    /* t1 = t2 */
-    if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-
-    /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
-
-    /* t3 = t1**(b-1) */
-    if ((res = mp_expt_d_ex (&t1, b - 1, &t3, fast)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-
-    /* numerator */
-    /* t2 = t1**b */
-    if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-
-    /* t2 = t1**b - a */
-    if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-
-    /* denominator */
-    /* t3 = t1**(b-1) * b  */
-    if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-
-    /* t3 = (t1**b - a)/(b * t1**(b-1)) */
-    if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-
-    if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-  }  while (mp_cmp (&t1, &t2) != MP_EQ);
-
-  /* result can be off by a few so check */
-  for (;;) {
-    if ((res = mp_expt_d_ex (&t1, b, &t2, fast)) != MP_OKAY) {
-      goto LBL_T3;
-    }
-
-    if (mp_cmp (&t2, a) == MP_GT) {
-      if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
-         goto LBL_T3;
-      }
-    } else {
-      break;
-    }
-  }
-
-  /* reset the sign of a first */
-  a->sign = neg;
-
-  /* set the result */
-  mp_exch (&t1, c);
-
-  /* set the sign of the result */
-  c->sign = neg;
-
-  res = MP_OKAY;
-
-LBL_T3:mp_clear (&t3);
-LBL_T2:mp_clear (&t2);
-LBL_T1:mp_clear (&t1);
-  return res;
-}
-#endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_neg.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_neg.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,40 +1,24 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_NEG_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* b = -a */
-int mp_neg (mp_int * a, mp_int * b)
+mp_err mp_neg(const mp_int *a, mp_int *b)
 {
-  int     res;
-  if (a != b) {
-     if ((res = mp_copy (a, b)) != MP_OKAY) {
-        return res;
-     }
-  }
+   mp_err err;
+   if (a != b) {
+      if ((err = mp_copy(a, b)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-  if (mp_iszero(b) != MP_YES) {
-     b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
-  } else {
-     b->sign = MP_ZPOS;
-  }
+   if (!MP_IS_ZERO(b)) {
+      b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+   } else {
+      b->sign = MP_ZPOS;
+   }
 
-  return MP_OKAY;
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- a/libtommath/bn_mp_or.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_or.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,50 +1,56 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_OR_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
-/* OR two ints together */
-int mp_or (mp_int * a, mp_int * b, mp_int * c)
+/* two complement or */
+mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c)
 {
-  int     res, ix, px;
-  mp_int  t, *x;
+   int used = MP_MAX(a->used, b->used) + 1, i;
+   mp_err err;
+   mp_digit ac = 1, bc = 1, cc = 1;
+   mp_sign csign = ((a->sign == MP_NEG) || (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS;
+
+   if (c->alloc < used) {
+      if ((err = mp_grow(c, used)) != MP_OKAY) {
+         return err;
+      }
+   }
+
+   for (i = 0; i < used; i++) {
+      mp_digit x, y;
+
+      /* convert to two complement if negative */
+      if (a->sign == MP_NEG) {
+         ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
+         x = ac & MP_MASK;
+         ac >>= MP_DIGIT_BIT;
+      } else {
+         x = (i >= a->used) ? 0uL : a->dp[i];
+      }
 
-  if (a->used > b->used) {
-    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
-      return res;
-    }
-    px = b->used;
-    x = b;
-  } else {
-    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
-      return res;
-    }
-    px = a->used;
-    x = a;
-  }
+      /* convert to two complement if negative */
+      if (b->sign == MP_NEG) {
+         bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
+         y = bc & MP_MASK;
+         bc >>= MP_DIGIT_BIT;
+      } else {
+         y = (i >= b->used) ? 0uL : b->dp[i];
+      }
+
+      c->dp[i] = x | y;
 
-  for (ix = 0; ix < px; ix++) {
-    t.dp[ix] |= x->dp[ix];
-  }
-  mp_clamp (&t);
-  mp_exch (c, &t);
-  mp_clear (&t);
-  return MP_OKAY;
+      /* convert to to sign-magnitude if negative */
+      if (csign == MP_NEG) {
+         cc += ~c->dp[i] & MP_MASK;
+         c->dp[i] = cc & MP_MASK;
+         cc >>= MP_DIGIT_BIT;
+      }
+   }
+
+   c->used = used;
+   c->sign = csign;
+   mp_clamp(c);
+   return MP_OKAY;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_pack.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,69 @@
+#include "tommath_private.h"
+#ifdef BN_MP_PACK_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* based on gmp's mpz_export.
+ * see http://gmplib.org/manual/Integer-Import-and-Export.html
+ */
+mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order, size_t size,
+               mp_endian endian, size_t nails, const mp_int *op)
+{
+   mp_err err;
+   size_t odd_nails, nail_bytes, i, j, count;
+   unsigned char odd_nail_mask;
+
+   mp_int t;
+
+   count = mp_pack_count(op, nails, size);
+
+   if (count > maxcount) {
+      return MP_BUF;
+   }
+
+   if ((err = mp_init_copy(&t, op)) != MP_OKAY) {
+      return err;
+   }
+
+   if (endian == MP_NATIVE_ENDIAN) {
+      MP_GET_ENDIANNESS(endian);
+   }
+
+   odd_nails = (nails % 8u);
+   odd_nail_mask = 0xff;
+   for (i = 0u; i < odd_nails; ++i) {
+      odd_nail_mask ^= (unsigned char)(1u << (7u - i));
+   }
+   nail_bytes = nails / 8u;
+
+   for (i = 0u; i < count; ++i) {
+      for (j = 0u; j < size; ++j) {
+         unsigned char *byte = (unsigned char *)rop +
+                               (((order == MP_LSB_FIRST) ? i : ((count - 1u) - i)) * size) +
+                               ((endian == MP_LITTLE_ENDIAN) ? j : ((size - 1u) - j));
+
+         if (j >= (size - nail_bytes)) {
+            *byte = 0;
+            continue;
+         }
+
+         *byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL));
+
+         if ((err = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) {
+            goto LBL_ERR;
+         }
+
+      }
+   }
+
+   if (written != NULL) {
+      *written = count;
+   }
+   err = MP_OKAY;
+
+LBL_ERR:
+   mp_clear(&t);
+   return err;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_pack_count.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,12 @@
+#include "tommath_private.h"
+#ifdef BN_MP_PACK_COUNT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+size_t mp_pack_count(const mp_int *a, size_t nails, size_t size)
+{
+   size_t bits = (size_t)mp_count_bits(a);
+   return ((bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u));
+}
+
+#endif
--- a/libtommath/bn_mp_prime_fermat.c	Thu Mar 21 23:28:59 2019 +0800
+++ b/libtommath/bn_mp_prime_fermat.c	Fri Jun 26 21:07:34 2020 +0800
@@ -1,62 +1,47 @@
-#include <tommath_private.h>
+#include "tommath_private.h"
 #ifdef BN_MP_PRIME_FERMAT_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* performs one Fermat test.
- * 
+ *
  * If "a" were prime then b**a == b (mod a) since the order of
  * the multiplicative sub-group would be phi(a) = a-1.  That means
  * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
  *
  * Sets result to 1 if the congruence holds, or zero otherwise.
  */
-int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
+mp_err mp_prime_fermat(const mp_int *a, const mp_int *b, mp_bool *result)
 {
-  mp_int  t;
-  int     err;
+   mp_int  t;
+   mp_err  err;
 
-  /* default to composite  */
-  *result = MP_NO;
+   /* default to composite  */
+   *result = MP_NO;
 
-  /* ensure b > 1 */
-  if (mp_cmp_d(b, 1) != MP_GT) {
-     return MP_VAL;
-  }
+   /* ensure b > 1 */
+   if (mp_cmp_d(b, 1uL) != MP_GT) {
+      return MP_VAL;
+   }
 
-  /* init t */
-  if ((err = mp_init (&t)) != MP_OKAY) {
-    return err;
-  }
+   /* init t */
+   if ((err = mp_init(&t)) != MP_OKAY) {
+      return err;
+   }
+
+   /* compute t = b**a mod a */
+   if ((err = mp_exptmod(b, a, a, &t)) != MP_OKAY) {
+      goto LBL_T;
+   }
 
-  /* compute t = b**a mod a */
-  if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
-    goto LBL_T;
-  }
+   /* is it equal to b? */
+   if (mp_cmp(&t, b) == MP_EQ) {
+      *result = MP_YES;
+   }
 
-  /* is it equal to b? */
-  if (mp_cmp (&t, b) == MP_EQ) {
-    *result = MP_YES;
-  }
-
-  err = MP_OKAY;
-LBL_T:mp_clear (&t);
-  return err;
+   err = MP_OKAY;
+LBL_T:
+   mp_clear(&t);
+   return err;
 }
 #endif
-
-/* ref:         $Format:%D$ */
-/* git commit:  $Format:%H$ */
-/* commit time: $Format:%ai$ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtommath/bn_mp_prime_frobenius_underwood.c	Fri Jun 26 21:07:34 2020 +0800
@@ -0,0 +1,132 @@
+#include "tommath_private.h"
+#ifdef BN_MP_PRIME_FROBENIUS_UNDERWOOD_C
+
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/*
+ *  See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details
+ */
+#ifndef LTM_USE_ONLY_MR
+
+#ifdef MP_8BIT
+/*
+ * floor of positive solution of
+ * (2^16)-1 = (a+4)*(2*a+5)
+ * TODO: Both values are smaller than N^(1/4), would have to use a bigint
+ *       for a instead but any a biger than about 120 are already so rare that
+ *       it is possible to ignore them and still get enough pseudoprimes.
+ *       But it is still a restriction of the set of available pseudoprimes
+ *       which makes this implementation less secure if used stand-alone.
+ */
+#define LTM_FROBENIUS_UNDERWOOD_A 177
+#else
+#define LTM_FROBENIUS_UNDERWOOD_A 32764
+#endif
+mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result)
+{
+   mp_int T1z, T2z, Np1z, sz, tz;
+
+   int a, ap2, length, i, j;
+   mp_err err;
+
+   *result = MP_NO;
+
+   if ((err = mp_init_multi(&T1z, &T2z, &Np1z, &sz, &tz, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   for (a = 0; a < LTM_FROBENIUS_UNDERWOOD_A; a++) {
+      /* TODO: That's ugly! No, really, it is! */
+      if ((a==2) || (a==4) || (a==7) || (a==8) || (a==10) ||
+          (a==14) || (a==18) || (a==23) || (a==26) || (a==28)) {
+         continue;
+      }
+      /* (32764^2 - 4) < 2^31, no bigint for >MP_8BIT needed) */
+      mp_set_u32(&T1z, (uint32_t)a);
+
+      if ((err = mp_sqr(&T1z, &T1z)) != MP_OKAY)                  goto LBL_FU_ERR;
+
+      if ((err = mp_sub_d(&T1z, 4uL, &T1z)) != MP_OKAY)           goto LBL_FU_ERR;
+
+      if ((err = mp_kronecker(&T1z, N, &j)) != MP_OKAY)           goto LBL_FU_ERR;
+
+      if (j == -1) {
+         break;
+      }
+
+      if (j == 0) {
+         /* composite */
+         goto LBL_FU_ERR;
+      }
+   }
+   /* Tell it a composite and set return value accordingly */
+   if (a >= LTM_FROBENIUS_UNDERWOOD_A) {
+      err = MP_ITER;
+      goto LBL_FU_ERR;
+   }
+   /* Composite if N and (a+4)*(2*a+5) are not coprime */
+   mp_set_u32(&T1z, (uint32_t)((a+4)*((2*a)+5)));
+
+   if ((err = mp_gcd(N, &T1z, &T1z)) != MP_OKAY)                  goto LBL_FU_ERR;
+