diff --git a/.gitignore b/.gitignore index 2ab5799..007dd7c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /libxcrypt-4.0.0-20180120git3436e7b.tar.gz /libxcrypt-4.0.0.tar.gz /libxcrypt-4.0.1.tar.gz +/libxcrypt-4.1.0.tar.gz diff --git a/libxcrypt-4.0.1_to_develop.patch b/libxcrypt-4.0.1_to_develop.patch deleted file mode 100644 index d6c0aad..0000000 --- a/libxcrypt-4.0.1_to_develop.patch +++ /dev/null @@ -1,12909 +0,0 @@ -From 0bf9b35bb04b9f35a43e2ff6493d6a5ecc3c9db1 Mon Sep 17 00:00:00 2001 -From: Thorsten Kukuk -Date: Tue, 22 May 2018 11:42:07 +0200 -Subject: [PATCH 01/41] Fix spelling of SUSE - ---- - Makefile.am | 4 ++-- - README.md | 2 +- - libcrypt.map.in | 2 +- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index a7e726f..90fe733 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -71,7 +71,7 @@ crypt.h: crypt-base.h gen-crypt-h.awk config.h - $(AM_V_at)mv -f crypt.h.T crypt.h - - # When we are being binary compatible, also install symbolic links to --# mimic SuSE's libowcrypt; any program that uses -lowcrypt in its -+# mimic SUSE's libowcrypt; any program that uses -lowcrypt in its - # build, or already has a NEEDED entry for libowcrypt.so.1, will be - # redirected to libcrypt. The OW_CRYPT_1.0 symbol versions are already - # present in libcrypt.so.1. -@@ -80,7 +80,7 @@ crypt.h: crypt-base.h gen-crypt-h.awk config.h - # libraries involved, libcrypt.so.1 and libowcrypt.so.1. (We should - # be able to get away with this because in any circumstance where the - # soname of libcrypt isn't libcrypt.so.1, ENABLE_OBSOLETE_API should --# be automatically turned off, and as best I can tell, SuSE only ever -+# be automatically turned off, and as best I can tell, SUSE only ever - # shipped libowcrypt.so.1.) - if ENABLE_OBSOLETE_API - if ENABLE_STATIC -diff --git a/README.md b/README.md -index 05319f3..869d46f 100644 ---- a/README.md -+++ b/README.md -@@ -75,7 +75,7 @@ libcrypt.so.1. We have taken pains to provide exactly the same - "symbol versions" as were used by glibc on various CPU architectures, - and to account for the variety of ways in which the Openwall - extensions were patched into glibc's libcrypt by some Linux --distributions. (For instance, compatibility symlinks for SuSE's -+distributions. (For instance, compatibility symlinks for SUSE's - "libowcrypt" are provided.) - - However, the converse is not true: programs linked against libxcrypt -diff --git a/libcrypt.map.in b/libcrypt.map.in -index 2de7d1b..18aac79 100644 ---- a/libcrypt.map.in -+++ b/libcrypt.map.in -@@ -7,7 +7,7 @@ crypt XCRYPT_2.0 GLIBC_2.0 - crypt_r XCRYPT_2.0 GLIBC_2.0 - - # Actively supported Openwall extensions; never actually added to --# upstream GNU libc, but present in at least Openwall, ALT, and SuSE -+# upstream GNU libc, but present in at least Openwall, ALT, and SUSE - # Linux distributions with one or more of these symbol versions - crypt_rn XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 - crypt_gensalt XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 OW_CRYPT_1.0 - -From 089d679b81a3c4e821f5f9cfaacb33e67370eeed Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 22 Jun 2018 00:07:54 +0000 -Subject: [PATCH 02/41] Lower the minimum required automake version - -The minimum required automake version was raised from 1.7 to 1.15 by -commit a6c11d6cd89ac391dfb81bc2b7eb2b9fb31d7da6. This new requirement -seems to be unnecessarily high, at least, the project builds using -automake 1.14 just fine. ---- - Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index 90fe733..491dfae 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -4,7 +4,7 @@ - # Author: Thorsten Kukuk - # - --AUTOMAKE_OPTIONS = 1.15 gnits -+AUTOMAKE_OPTIONS = 1.14 gnits - ACLOCAL_AMFLAGS = -I m4 - - AM_CFLAGS = $(WARN_CFLAGS) - -From fab17cc338b3e18cb74ebed8da3a876e485e3c95 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 22 Jun 2018 00:07:54 +0000 -Subject: [PATCH 03/41] gen-vers.awk: fix typo in comment - ---- - gen-vers.awk | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gen-vers.awk b/gen-vers.awk -index 602195a..4870d05 100644 ---- a/gen-vers.awk -+++ b/gen-vers.awk -@@ -15,7 +15,7 @@ - # the macros generated by this program. - # - # Note: if you change the format of .map.in files you probably need to --# update gen-vers.awk too. -+# update gen-map.awk too. - # - # Note: we currently don't support compatibility symbols that need - # a different definition from the default version. - -From b1d83b002039a561233ce55986d9205e76138a14 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Wed, 27 Jun 2018 14:58:49 +0000 -Subject: [PATCH 04/41] Fix build with USE_SWAPCONTEXT turned off - -Due to regression introduced by commit v4.0.0~100, the project no longer -builds when USE_SWAPCONTEXT is not available or explicitly turned off. -This is not a very big deal as this build mode seems to be not very -popular, but fix it anyway. ---- - crypt.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/crypt.c b/crypt.c -index d7f0ffc..2aa9491 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -288,7 +288,7 @@ do_crypt (const char *phrase, const char *setting, struct crypt_data *data) - swapcontext (&outer_ctx, &cint->inner_ctx); - } - #else -- cfn (phrase, setting, -+ h->crypt (phrase, setting, - (unsigned char *)data->output, sizeof data->output, - cint->alg_specific, sizeof cint->alg_specific); - #endif - -From 942d51bbe41f6f84138916c2b180b5b669d65b27 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 29 Jun 2018 11:07:48 +0000 -Subject: [PATCH 05/41] Include crypt-port.h in two remaining source files - -crypt-port.h must be the first header file included by each source file, -this guarantees that config.h is included before any system header. ---- - test-crypt-badsalt.c | 1 + - test-crypt-nonnull.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c -index 1e1e840..c46848d 100644 ---- a/test-crypt-badsalt.c -+++ b/test-crypt-badsalt.c -@@ -16,6 +16,7 @@ - License along with the GNU C Library; if not, see - . */ - -+#include "crypt-port.h" - #include - #include - #include -diff --git a/test-crypt-nonnull.c b/test-crypt-nonnull.c -index 27313f0..5e4f118 100644 ---- a/test-crypt-nonnull.c -+++ b/test-crypt-nonnull.c -@@ -16,6 +16,7 @@ - License along with the GNU C Library; if not, see - . */ - -+#include "crypt-port.h" - #include - #include - #include - -From e9b661ffd4d58788f61c46ad1e8e29380b43f464 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 29 Jun 2018 11:07:48 +0000 -Subject: [PATCH 06/41] Use ARRAY_SIZE instead of open-coding it in every use - case - -Introduce ARRAY_SIZE macro, use it in all cases like -sizeof (tests) / sizeof (tests[0]) - -The definition of ARRAY_SIZE is the simplest one, a guard that -its argument is an array can be added later if necessary. ---- - crypt-port.h | 3 +++ - test-alg-md4.c | 2 +- - test-alg-md5.c | 2 +- - test-alg-sha256.c | 2 +- - test-alg-sha512.c | 2 +- - test-byteorder.c | 8 ++++---- - test-crypt-badsalt.c | 2 +- - test-crypt-des.c | 2 +- - test-crypt-nonnull.c | 2 +- - test-crypt-nthash.c | 2 +- - test-crypt-pbkdf1-sha1.c | 2 +- - test-crypt-sha256.c | 2 +- - test-crypt-sha512.c | 2 +- - test-crypt-sunmd5.c | 2 +- - test-des-cases.h | 2 +- - test-gensalt.c | 2 +- - 16 files changed, 21 insertions(+), 18 deletions(-) - -diff --git a/crypt-port.h b/crypt-port.h -index 2b74ec9..99717f3 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -87,6 +87,9 @@ typedef union - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) - #define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -+/* ARRAY_SIZE is used in tests. */ -+#define ARRAY_SIZE(a_) (sizeof (a_) / sizeof ((a_)[0])) -+ - /* Provide a guaranteed way to erase sensitive memory at the best we - can, given the possibilities of the system. */ - #if defined HAVE_MEMSET_S -diff --git a/test-alg-md4.c b/test-alg-md4.c -index 3476c35..ab6ad87 100644 ---- a/test-alg-md4.c -+++ b/test-alg-md4.c -@@ -73,7 +73,7 @@ main (void) - int cnt; - int i; - -- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt) -+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt) - { - md4_init_ctx (&ctx); - md4_process_bytes ((const unsigned char*)tests[cnt].input, &ctx, strlen (tests[cnt].input)); -diff --git a/test-alg-md5.c b/test-alg-md5.c -index 8bde121..9908ab8 100644 ---- a/test-alg-md5.c -+++ b/test-alg-md5.c -@@ -80,7 +80,7 @@ main (void) - int cnt; - int i; - -- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt) -+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt) - { - md5_init_ctx (&ctx); - md5_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx); -diff --git a/test-alg-sha256.c b/test-alg-sha256.c -index 86b1e8c..45345e2 100644 ---- a/test-alg-sha256.c -+++ b/test-alg-sha256.c -@@ -88,7 +88,7 @@ main (void) - int cnt; - int i; - -- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt) -+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt) - { - sha256_init_ctx (&ctx); - sha256_process_bytes (tests[cnt].input, strlen (tests[cnt].input), -diff --git a/test-alg-sha512.c b/test-alg-sha512.c -index d6eae93..0e24ad5 100644 ---- a/test-alg-sha512.c -+++ b/test-alg-sha512.c -@@ -116,7 +116,7 @@ main (void) - int cnt; - int i; - -- for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt) -+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt) - { - sha512_init_ctx (&ctx); - sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input), -diff --git a/test-byteorder.c b/test-byteorder.c -index 58bc9a7..7be0895 100644 ---- a/test-byteorder.c -+++ b/test-byteorder.c -@@ -46,7 +46,7 @@ test_le32 (void) - { 0x000000FF, "\xFF\x00\x00\x00" }, - { 0x01234567, "\x67\x45\x23\x01" }, - }; -- size_t n_cases = sizeof cases / sizeof cases[0]; -+ size_t n_cases = ARRAY_SIZE (cases); - size_t i; - uint32_t v; - unsigned char x[4]; -@@ -93,7 +93,7 @@ test_be32 (void) - { 0x000000FF, "\x00\x00\x00\xFF" }, - { 0x01234567, "\x01\x23\x45\x67" }, - }; -- size_t n_cases = sizeof cases / sizeof cases[0]; -+ size_t n_cases = ARRAY_SIZE (cases); - size_t i; - uint32_t v; - unsigned char x[4]; -@@ -144,7 +144,7 @@ test_le64 (void) - { 0xFF00000000000000ull, "\x00\x00\x00\x00\x00\x00\x00\xFF" }, - { 0x0123456789ABCDEFull, "\xEF\xCD\xAB\x89\x67\x45\x23\x01" }, - }; -- size_t n_cases = sizeof cases / sizeof cases[0]; -+ size_t n_cases = ARRAY_SIZE (cases); - size_t i; - uint64_t v; - unsigned char x[8]; -@@ -201,7 +201,7 @@ test_be64 (void) - { 0xFF00000000000000ull, "\xFF\x00\x00\x00\x00\x00\x00\x00" }, - { 0x0123456789ABCDEFull, "\x01\x23\x45\x67\x89\xAB\xCD\xEF" }, - }; -- size_t n_cases = sizeof cases / sizeof cases[0]; -+ size_t n_cases = ARRAY_SIZE (cases); - size_t i; - uint64_t v; - unsigned char x[8]; -diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c -index c46848d..a5e0e01 100644 ---- a/test-crypt-badsalt.c -+++ b/test-crypt-badsalt.c -@@ -45,7 +45,7 @@ main (void) - int result = 0; - struct crypt_data cd; - struct crypt_data *cdptr = &cd; -- size_t n = sizeof (tests) / sizeof (*tests); -+ size_t n = ARRAY_SIZE (tests); - size_t pagesize = (size_t) sysconf (_SC_PAGESIZE); - char *page, *retval; - const char *saltstr, *special = "%"; -diff --git a/test-crypt-des.c b/test-crypt-des.c -index d2266e4..dbe44e0 100644 ---- a/test-crypt-des.c -+++ b/test-crypt-des.c -@@ -65,7 +65,7 @@ static const struct - }, - }; - --#define ntests (sizeof (tests) / sizeof (tests[0])) -+#define ntests ARRAY_SIZE (tests) - - int - main (void) -diff --git a/test-crypt-nonnull.c b/test-crypt-nonnull.c -index 5e4f118..e4738ff 100644 ---- a/test-crypt-nonnull.c -+++ b/test-crypt-nonnull.c -@@ -44,7 +44,7 @@ main (void) - int result = 0; - struct crypt_data cd; - struct crypt_data *cdptr = &cd; -- size_t n = sizeof (tests) / sizeof (*tests); -+ size_t n = ARRAY_SIZE (tests); - size_t pagesize = (size_t) sysconf (_SC_PAGESIZE); - char *page; - const char *saltstr, *special = "%"; -diff --git a/test-crypt-nthash.c b/test-crypt-nthash.c -index dc1f320..6f897fe 100644 ---- a/test-crypt-nthash.c -+++ b/test-crypt-nthash.c -@@ -120,7 +120,7 @@ static const struct - } - }; - --#define ntests (sizeof (tests) / sizeof (tests[0])) -+#define ntests ARRAY_SIZE (tests) - - int - main (void) -diff --git a/test-crypt-pbkdf1-sha1.c b/test-crypt-pbkdf1-sha1.c -index c86abd4..aadc0fe 100644 ---- a/test-crypt-pbkdf1-sha1.c -+++ b/test-crypt-pbkdf1-sha1.c -@@ -58,7 +58,7 @@ const char *tests[][2] = - }, - }; - --#define ntests (sizeof (tests) / sizeof (tests[0])) -+#define ntests ARRAY_SIZE (tests) - - int - main (void) -diff --git a/test-crypt-sha256.c b/test-crypt-sha256.c -index c742aae..23da81c 100644 ---- a/test-crypt-sha256.c -+++ b/test-crypt-sha256.c -@@ -48,7 +48,7 @@ static const struct - }, - }; - --#define ntests (sizeof (tests) / sizeof (tests[0])) -+#define ntests ARRAY_SIZE (tests) - - - -diff --git a/test-crypt-sha512.c b/test-crypt-sha512.c -index a18cea8..1aa0b71 100644 ---- a/test-crypt-sha512.c -+++ b/test-crypt-sha512.c -@@ -49,7 +49,7 @@ static const struct - "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." - }, - }; --#define ntests (sizeof (tests) / sizeof (tests[0])) -+#define ntests ARRAY_SIZE (tests) - - - int -diff --git a/test-crypt-sunmd5.c b/test-crypt-sunmd5.c -index d4fc0dc..d67781b 100644 ---- a/test-crypt-sunmd5.c -+++ b/test-crypt-sunmd5.c -@@ -88,7 +88,7 @@ const char *tests[][3] = - }, - }; - --#define ntests (sizeof (tests) / sizeof (tests[0])) -+#define ntests ARRAY_SIZE (tests) - - int - main (void) -diff --git a/test-des-cases.h b/test-des-cases.h -index 03ca837..8354df7 100644 ---- a/test-des-cases.h -+++ b/test-des-cases.h -@@ -191,6 +191,6 @@ static const struct des_testcase des_testcases[] = - { "\x01\x83\x10\xdc\x40\x9b\x26\xd6", "\x1d\x9d\x5c\x50\x18\xf7\x28\xc2", "\x5f\x4c\x03\x8e\xd1\x2b\x2e\x41" }, - { "\x1c\x58\x7f\x1c\x13\x92\x4f\xef", "\x30\x55\x32\x28\x6d\x6f\x29\x5a", "\x63\xfa\xc0\xd0\x34\xd9\xf7\x93" }, - }; --static const size_t N_DES_TESTCASES = sizeof des_testcases / sizeof des_testcases[0]; -+static const size_t N_DES_TESTCASES = ARRAY_SIZE (des_testcases); - - #endif /* test-des-cases.h */ -diff --git a/test-gensalt.c b/test-gensalt.c -index dfe194c..4b3a0e1 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -51,7 +51,7 @@ main (void) - for (tcase = testcases; tcase->prefix; tcase++) - { - XCRYPT_SECURE_MEMSET (prev_output, CRYPT_GENSALT_OUTPUT_SIZE); -- for (ent = 0; ent < (sizeof entropy / sizeof entropy[0]); ent++) -+ for (ent = 0; ent < ARRAY_SIZE (entropy); ent++) - { - XCRYPT_SECURE_MEMSET (output, CRYPT_GENSALT_OUTPUT_SIZE); - char *salt = crypt_gensalt_rn (tcase->prefix, 0, - -From 10483284a8fbefde59e71700089a28e3f18cbe5b Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 22 Jun 2018 00:07:54 +0000 -Subject: [PATCH 07/41] Extend --enable-weak-hashes configure option - -Extend --enable-weak-hashes configure option to accept optional "glibc" -parameter. When specified, it enables only those of weak hashes that -are supported by historic versions of the GNU libc. - -Closes: https://github.com/besser82/libxcrypt/issues/7 ---- - Makefile.am | 20 ++++++++++++++------ - configure.ac | 29 ++++++++++++++++++++++------- - crypt-des.c | 9 ++++++++- - crypt-port.h | 4 ++++ - crypt-private.h | 20 ++++++++++++++------ - crypt.c | 15 +++++++++++++++ - test-crypt-des.c | 2 ++ - test-gensalt.c | 4 +++- - 8 files changed, 82 insertions(+), 21 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index 491dfae..c219bac 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -114,9 +114,13 @@ check_PROGRAMS = \ - - if ENABLE_WEAK_HASHES - libcrypt_la_SOURCES += \ -- crypt-md5.c crypt-des.c crypt-nthash.c crypt-pbkdf1-sha1.c \ -- crypt-sunmd5.c \ -- alg-des.c alg-hmac-sha1.c alg-md4.c alg-md5.c alg-sha1.c -+ crypt-des.c crypt-md5.c alg-des.c alg-md5.c -+ -+if ENABLE_WEAK_NON_GLIBC_HASHES -+libcrypt_la_SOURCES += \ -+ crypt-nthash.c crypt-pbkdf1-sha1.c crypt-sunmd5.c \ -+ alg-hmac-sha1.c alg-md4.c alg-sha1.c -+endif - - nodist_libcrypt_la_SOURCES = \ - alg-des-tables.c -@@ -143,11 +147,15 @@ alg-des-tables.c: gen-des-tables - $(AM_V_at)mv -f alg-des-tables.c.T alg-des-tables.c - - check_PROGRAMS += \ -- test-alg-des test-alg-hmac-sha1 test-alg-md4 \ -- test-alg-md5 test-alg-sha1 \ -- test-crypt-badsalt test-crypt-des test-crypt-md5 \ -+ test-alg-des test-alg-md5 test-crypt-des test-crypt-md5 \ -+ test-crypt-badsalt -+ -+if ENABLE_WEAK_NON_GLIBC_HASHES -+check_PROGRAMS += \ -+ test-alg-hmac-sha1 test-alg-md4 test-alg-sha1 \ - test-crypt-nthash test-crypt-sunmd5 test-crypt-pbkdf1-sha1 - endif -+endif - - if ENABLE_OBSOLETE_API - libcrypt_la_SOURCES += crypt-des-obsolete.c -diff --git a/configure.ac b/configure.ac -index 9bc41d1..9846e3f 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -204,17 +204,28 @@ AC_ARG_ENABLE([obsolete-api], - - AC_ARG_ENABLE([weak-hashes], - AS_HELP_STRING( -- [--disable-weak-hashes], -- [do not include any support for weak hashes (DES, MD5). -- Implies --disable-obsolete-api, and breaks binary compatibility -- with glibc's libcrypt.] -+ [--enable-weak-hashes[=ARG]], -+ [When set to "yes", all of the hashing methods documented in crypt(5) -+ are supported for authenticating existing password hashes, including -+ several that are too weak to use for new passwords. -+ -+ When set to "glibc", only the weak hashes supported by historic -+ versions of GNU libc are supported: traditional DES and FreeBSD-style -+ MD5, but not bigcrypt-DES, BSDi extended DES, SHA1, SUNMD5, or NTHASH. -+ -+ When set to "no", only bcrypt, SHA512, and SHA256 are supported. -+ This mode implies --disable-obsolete-api and breaks binary -+ compatibility with glibc's libcrypt. -+ -+ [default=yes]] - ), - [case "${enableval}" in -- yes) enable_weak_hashes=1 ;; -- no) enable_weak_hashes=0 ;; -+ yes) enable_weak_hashes=1; enable_weak_non_glibc_hashes=1 ;; -+ glibc) enable_weak_hashes=1; enable_weak_non_glibc_hashes=0 ;; -+ no) enable_weak_hashes=0; enable_weak_non_glibc_hashes=0 ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-weak-hashes]) ;; - esac], -- [enable_weak_hashes=1] -+ [enable_weak_hashes=1; enable_weak_non_glibc_hashes=1] - ) - - # If weak hashes are disabled, then the obsolete APIs won't work anyway -@@ -293,6 +304,10 @@ AC_DEFINE_UNQUOTED([ENABLE_WEAK_HASHES], [$enable_weak_hashes], - If this is 0, ENABLE_OBSOLETE_API must also be 0.]) - AM_CONDITIONAL([ENABLE_WEAK_HASHES], [test $enable_weak_hashes = 1]) - -+AC_DEFINE_UNQUOTED([ENABLE_WEAK_NON_GLIBC_HASHES], [$enable_weak_non_glibc_hashes], -+ [Define as 1 if weak hashes not supported by glibc should be included, 0 otherwise.]) -+AM_CONDITIONAL([ENABLE_WEAK_NON_GLIBC_HASHES], [test $enable_weak_non_glibc_hashes = 1]) -+ - # The Makefile needs to know which versions of the library we are building. - AM_CONDITIONAL([ENABLE_STATIC], [test $enable_static = yes]) - AM_CONDITIONAL([ENABLE_SHARED], [test $enable_shared = yes]) -diff --git a/crypt-des.c b/crypt-des.c -index 467be8d..79b3144 100644 ---- a/crypt-des.c -+++ b/crypt-des.c -@@ -144,7 +144,10 @@ des_gen_hash (struct des_ctx *ctx, uint32_t count, uint8_t *output, - } - - /* The original UNIX DES-based password hash, no extensions. */ --static void -+#if ENABLE_WEAK_NON_GLIBC_HASHES -+static -+#endif -+void - crypt_des_trd_rn (const char *phrase, const char *setting, - uint8_t *output, size_t o_size, - void *scratch, size_t s_size) -@@ -192,6 +195,7 @@ crypt_des_trd_rn (const char *phrase, const char *setting, - des_gen_hash (ctx, 25, cp, pkbuf); - } - -+#if ENABLE_WEAK_NON_GLIBC_HASHES - /* This algorithm is algorithm 0 (default) shipped with the C2 secure - implementation of Digital UNIX. - -@@ -342,6 +346,7 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting, - des_set_salt (ctx, salt); - des_gen_hash (ctx, count, cp, pkbuf); - } -+#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */ - - void - gensalt_des_trd_rn (unsigned long count, -@@ -365,6 +370,7 @@ gensalt_des_trd_rn (unsigned long count, - output[2] = '\0'; - } - -+#if ENABLE_WEAK_NON_GLIBC_HASHES - void - gensalt_des_xbsd_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, -@@ -406,3 +412,4 @@ gensalt_des_xbsd_rn (unsigned long count, - - output[9] = '\0'; - } -+#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */ -diff --git a/crypt-port.h b/crypt-port.h -index 99717f3..8b21f56 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -217,7 +217,11 @@ void _xcrypt_secure_memset (void *s, size_t len) - #if ENABLE_WEAK_HASHES - #define comp_maskl _crypt_comp_maskl - #define comp_maskr _crypt_comp_maskr -+#if ENABLE_WEAK_NON_GLIBC_HASHES - #define crypt_des_trd_or_big_rn _crypt_crypt_des_trd_or_big_rn -+#else -+#define crypt_des_trd_rn _crypt_crypt_des_trd_rn -+#endif - #define crypt_des_xbsd_rn _crypt_crypt_des_xbsd_rn - #define crypt_md5_rn _crypt_crypt_md5_rn - #define crypt_nthash_rn _crypt_crypt_nthash_rn -diff --git a/crypt-private.h b/crypt-private.h -index 80a916d..c5db3bd 100644 ---- a/crypt-private.h -+++ b/crypt-private.h -@@ -39,15 +39,16 @@ extern void gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount, - /* Individual hash functions */ - - #if ENABLE_WEAK_HASHES -+extern void crypt_md5_rn (const char *phrase, const char *setting, -+ uint8_t *output, size_t o_size, -+ void *scratch, size_t s_size); -+#if ENABLE_WEAK_NON_GLIBC_HASHES - extern void crypt_des_trd_or_big_rn (const char *phrase, const char *setting, - uint8_t *output, size_t o_size, - void *scratch, size_t s_size); - extern void crypt_des_xbsd_rn (const char *phrase, const char *setting, - uint8_t *output, size_t o_size, - void *scratch, size_t s_size); --extern void crypt_md5_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); - extern void crypt_nthash_rn (const char *phrase, const char *setting, - uint8_t *output, size_t o_size, - void *scratch, size_t s_size); -@@ -57,6 +58,11 @@ extern void crypt_sha1_rn (const char *phrase, const char *setting, - extern void crypt_sunmd5_rn (const char *phrase, const char *setting, - uint8_t *output, size_t o_size, - void *scratch, size_t s_size); -+#else -+extern void crypt_des_trd_rn (const char *phrase, const char *setting, -+ uint8_t *output, size_t o_size, -+ void *scratch, size_t s_size); -+#endif - #endif - - extern void crypt_sha256_rn (const char *phrase, const char *setting, -@@ -73,12 +79,13 @@ extern void crypt_bcrypt_rn (const char *phrase, const char *setting, - extern void gensalt_des_trd_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, - uint8_t *output, size_t o_size); --extern void gensalt_des_xbsd_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); - extern void gensalt_md5_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, - uint8_t *output, size_t o_size); -+#if ENABLE_WEAK_NON_GLIBC_HASHES -+extern void gensalt_des_xbsd_rn (unsigned long count, -+ const uint8_t *rbytes, size_t nrbytes, -+ uint8_t *output, size_t o_size); - extern void gensalt_nthash_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, - uint8_t *output, size_t o_size); -@@ -89,6 +96,7 @@ extern void gensalt_sunmd5_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, - uint8_t *output, size_t o_size); - #endif -+#endif - - extern void gensalt_sha256_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, -diff --git a/crypt.c b/crypt.c -index 2aa9491..38dfca9 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -87,9 +87,11 @@ static const struct hashfn tagged_hashes[] = - /* legacy hashes */ - #if ENABLE_WEAK_HASHES - { "$1$", crypt_md5_rn, gensalt_md5_rn }, -+#if ENABLE_WEAK_NON_GLIBC_HASHES - { "$3$", crypt_nthash_rn, gensalt_nthash_rn }, - { "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn }, - { "$sha1", crypt_sha1_rn, gensalt_sha1_rn }, -+#endif - #endif - { "$5$", crypt_sha256_rn, gensalt_sha256_rn }, - { "$6$", crypt_sha512_rn, gensalt_sha512_rn }, -@@ -97,6 +99,7 @@ static const struct hashfn tagged_hashes[] = - }; - - #if ENABLE_WEAK_HASHES -+#if ENABLE_WEAK_NON_GLIBC_HASHES - /* BSD-style extended DES */ - static const struct hashfn bsdi_extended_hash = - { -@@ -109,6 +112,16 @@ static const struct hashfn traditional_hash = - "", crypt_des_trd_or_big_rn, gensalt_des_trd_rn - }; - -+#else -+ -+/* Traditional DES */ -+static const struct hashfn traditional_hash = -+{ -+ "", crypt_des_trd_rn, gensalt_des_trd_rn -+}; -+ -+#endif -+ - static int - is_des_salt_char (char c) - { -@@ -131,8 +144,10 @@ get_hashfn (const char *setting) - return 0; - } - #if ENABLE_WEAK_HASHES -+#if ENABLE_WEAK_NON_GLIBC_HASHES - else if (setting[0] == '_') - return &bsdi_extended_hash; -+#endif - else if (setting[0] == '\0' || - (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1]))) - return &traditional_hash; -diff --git a/test-crypt-des.c b/test-crypt-des.c -index dbe44e0..e541885 100644 ---- a/test-crypt-des.c -+++ b/test-crypt-des.c -@@ -20,6 +20,7 @@ static const struct - { "XX", "XXxzOu6maQKqQ", "*U*U*U*U" }, - { "SD", "SDbsugeBiC58A", "" }, - -+#if ENABLE_WEAK_NON_GLIBC_HASHES - /* BSDI-extended-DES, ditto */ - { "_J9..CCCC", "_J9..CCCCXBrJUJV154M", "U*U*U*U*" }, - { "_J9..CCCC", "_J9..CCCCXUhOBTXzaiE", "U*U***U" }, -@@ -63,6 +64,7 @@ static const struct - "6M..............", "6MvZdspyAL4QEId8ugLUEeDs", - "\xf3\xf4\xe5\xf0\xe8\xe1\xee\xe9\xe5" /* stephanie */ - }, -+#endif - }; - - #define ntests ARRAY_SIZE (tests) -diff --git a/test-gensalt.c b/test-gensalt.c -index 4b3a0e1..39a5435 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -24,11 +24,13 @@ static const struct testcase testcases[] = - { - #if ENABLE_WEAK_HASHES - { "", 2 }, // DES -- { "_", 9 }, // BSDi extended DES - { "$1$", 11 }, // MD5 -+#if ENABLE_WEAK_NON_GLIBC_HASHES -+ { "_", 9 }, // BSDi extended DES - { "$3$", 29 }, // NTHASH - { "$md5", 27 }, // SUNMD5 - { "$sha1", 34 }, // PBKDF with SHA1 -+#endif - #endif - { "$5$", 19 }, // SHA-2-256 - { "$6$", 19 }, // SHA-2-512 - -From 84134e4d8e773fa6e27df1de2088f001e8042ef2 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Tue, 26 Jun 2018 22:45:01 +0000 -Subject: [PATCH 08/41] crypt_gensalt_rn: fix the number of automatically - obtained random bytes - -Commit v4.0.0~94 extended crypt_gensalt_ra to obtained random bytes -automatically when rbytes argument is NULL. The number of random bytes -was fixed to 16, subsequent commit v4.0.0~6 changed this fixed number -to 18. However, the approach of using a fixed number for every -algorithm has two problems. Firstly, it is too wasteful for some -of currently implemented algorithms that use less than 18 bytes -of randomness. Secondly, other algorithms can use more than 18 random -bytes. Fix these issues by specifying the number of random bytes along -with functions in tagged_hashes table. ---- - crypt.c | 43 ++++++++++++++++++++++--------------------- - test-gensalt.c | 34 +++++++++++++++++++--------------- - 2 files changed, 41 insertions(+), 36 deletions(-) - -diff --git a/crypt.c b/crypt.c -index 38dfca9..26f3537 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -21,9 +21,9 @@ - - #include - #include -+#include - - #ifdef USE_SWAPCONTEXT --#include - #include - #endif - -@@ -72,6 +72,9 @@ struct hashfn - const char *prefix; - crypt_fn crypt; - gensalt_fn gensalt; -+ /* The type of this field is unsigned char to ensure that it cannot -+ be set larger than the size of an internal buffer in crypt_gensalt_rn. */ -+ unsigned char nrbytes; - }; - - /* This table should always begin with the algorithm that should be used -@@ -79,23 +82,23 @@ struct hashfn - static const struct hashfn tagged_hashes[] = - { - /* bcrypt */ -- { "$2b$", crypt_bcrypt_rn, gensalt_bcrypt_b_rn }, -- { "$2a$", crypt_bcrypt_rn, gensalt_bcrypt_a_rn }, -- { "$2x$", crypt_bcrypt_rn, gensalt_bcrypt_x_rn }, -- { "$2y$", crypt_bcrypt_rn, gensalt_bcrypt_y_rn }, -+ { "$2b$", crypt_bcrypt_rn, gensalt_bcrypt_b_rn, 16 }, -+ { "$2a$", crypt_bcrypt_rn, gensalt_bcrypt_a_rn, 16 }, -+ { "$2x$", crypt_bcrypt_rn, gensalt_bcrypt_x_rn, 16 }, -+ { "$2y$", crypt_bcrypt_rn, gensalt_bcrypt_y_rn, 16 }, - - /* legacy hashes */ - #if ENABLE_WEAK_HASHES -- { "$1$", crypt_md5_rn, gensalt_md5_rn }, -+ { "$1$", crypt_md5_rn, gensalt_md5_rn, 9 }, - #if ENABLE_WEAK_NON_GLIBC_HASHES -- { "$3$", crypt_nthash_rn, gensalt_nthash_rn }, -- { "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn }, -- { "$sha1", crypt_sha1_rn, gensalt_sha1_rn }, -+ { "$3$", crypt_nthash_rn, gensalt_nthash_rn, 16 }, -+ { "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn, 8 }, -+ { "$sha1", crypt_sha1_rn, gensalt_sha1_rn, 48 }, - #endif - #endif -- { "$5$", crypt_sha256_rn, gensalt_sha256_rn }, -- { "$6$", crypt_sha512_rn, gensalt_sha512_rn }, -- { 0, 0, 0 } -+ { "$5$", crypt_sha256_rn, gensalt_sha256_rn, 15 }, -+ { "$6$", crypt_sha512_rn, gensalt_sha512_rn, 15 }, -+ { 0, 0, 0, 0 } - }; - - #if ENABLE_WEAK_HASHES -@@ -103,13 +106,13 @@ static const struct hashfn tagged_hashes[] = - /* BSD-style extended DES */ - static const struct hashfn bsdi_extended_hash = - { -- "_", crypt_des_xbsd_rn, gensalt_des_xbsd_rn -+ "_", crypt_des_xbsd_rn, gensalt_des_xbsd_rn, 3 - }; - - /* Traditional DES or bigcrypt-style extended DES */ - static const struct hashfn traditional_hash = - { -- "", crypt_des_trd_or_big_rn, gensalt_des_trd_rn -+ "", crypt_des_trd_or_big_rn, gensalt_des_trd_rn, 2 - }; - - #else -@@ -117,7 +120,7 @@ static const struct hashfn traditional_hash = - /* Traditional DES */ - static const struct hashfn traditional_hash = - { -- "", crypt_des_trd_rn, gensalt_des_trd_rn -+ "", crypt_des_trd_rn, gensalt_des_trd_rn, 2 - }; - - #endif -@@ -375,10 +378,6 @@ crypt_gensalt_rn (const char *prefix, unsigned long count, - const char *rbytes, int nrbytes, char *output, - int output_size) - { -- /* Always add two padding bytes to make sure the whole string -- will be random on Base64 encoding. */ -- char internal_rbytes[16 + 2]; -- - make_failure_token ("", output, output_size); - - /* Individual gensalt functions will check for adequate space for -@@ -404,15 +403,17 @@ crypt_gensalt_rn (const char *prefix, unsigned long count, - return 0; - } - -+ char internal_rbytes[UCHAR_MAX]; -+ - /* If rbytes is 0, read random bytes from the operating system if - possible. */ - if (!rbytes) - { -- if (!get_random_bytes(internal_rbytes, sizeof internal_rbytes)) -+ if (!get_random_bytes (internal_rbytes, h->nrbytes)) - return 0; - - rbytes = internal_rbytes; -- nrbytes = sizeof internal_rbytes; -+ nrbytes = h->nrbytes; - } - - /* Individual gensalt functions will check for sufficient random bits -diff --git a/test-gensalt.c b/test-gensalt.c -index 39a5435..f4d0629 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -18,27 +18,28 @@ struct testcase - { - const char *prefix; - unsigned int expected_len; -+ unsigned int expected_auto_len; - }; - - static const struct testcase testcases[] = - { - #if ENABLE_WEAK_HASHES -- { "", 2 }, // DES -- { "$1$", 11 }, // MD5 -+ { "", 2, 0 }, // DES -+ { "$1$", 11, 0 }, // MD5 - #if ENABLE_WEAK_NON_GLIBC_HASHES -- { "_", 9 }, // BSDi extended DES -- { "$3$", 29 }, // NTHASH -- { "$md5", 27 }, // SUNMD5 -- { "$sha1", 34 }, // PBKDF with SHA1 -+ { "_", 9, 0 }, // BSDi extended DES -+ { "$3$", 29, 0 }, // NTHASH -+ { "$md5", 27, 0 }, // SUNMD5 -+ { "$sha1", 34, 74 }, // PBKDF with SHA1 - #endif - #endif -- { "$5$", 19 }, // SHA-2-256 -- { "$6$", 19 }, // SHA-2-512 -- { "$2a$", 29 }, // bcrypt mode A -- { "$2b$", 29 }, // bcrypt mode B -- { "$2x$", 29 }, // bcrypt mode X -- { "$2y$", 29 }, // bcrypt mode Y -- { 0, 0 } -+ { "$5$", 19, 0 }, // SHA-2-256 -+ { "$6$", 19, 0 }, // SHA-2-512 -+ { "$2a$", 29, 0 }, // bcrypt mode A -+ { "$2b$", 29, 0 }, // bcrypt mode B -+ { "$2x$", 29, 0 }, // bcrypt mode X -+ { "$2y$", 29, 0 }, // bcrypt mode Y -+ { 0, 0, 0 } - }; - - int -@@ -74,11 +75,14 @@ main (void) - continue; - } - size_t slen = strlen (salt); -- if (slen != tcase->expected_len) -+ unsigned int expected_len = -+ (!entropy[ent] && tcase->expected_auto_len) ? -+ tcase->expected_auto_len : tcase->expected_len; -+ if (slen != expected_len) - { - fprintf (stderr, - "ERROR: %s/%u -> %s (expected len=%u got %zu)\n", -- tcase->prefix, ent, salt, tcase->expected_len, slen); -+ tcase->prefix, ent, salt, expected_len, slen); - status = 1; - } - else if (strncmp (salt, tcase->prefix, strlen (tcase->prefix))) - -From 2973606ece4ebc17ffea4882b090eec68555f0b0 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Wed, 27 Jun 2018 17:59:36 +0000 -Subject: [PATCH 09/41] crypt_gensalt_rn: fix the leak of obtained random bytes - -Erase the memory containing automatically obtained random bytes -to avoid leak of sensitive data after return from the function. ---- - crypt.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/crypt.c b/crypt.c -index 26f3537..12d50fd 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -404,6 +404,8 @@ crypt_gensalt_rn (const char *prefix, unsigned long count, - } - - char internal_rbytes[UCHAR_MAX]; -+ /* typeof (internal_nrbytes) == typeof (h->nrbytes). */ -+ unsigned char internal_nrbytes = 0; - - /* If rbytes is 0, read random bytes from the operating system if - possible. */ -@@ -413,7 +415,7 @@ crypt_gensalt_rn (const char *prefix, unsigned long count, - return 0; - - rbytes = internal_rbytes; -- nrbytes = h->nrbytes; -+ nrbytes = internal_nrbytes = h->nrbytes; - } - - /* Individual gensalt functions will check for sufficient random bits -@@ -429,6 +431,9 @@ crypt_gensalt_rn (const char *prefix, unsigned long count, - (const unsigned char *)rbytes, (size_t)nrbytes, - (unsigned char *)output, (size_t)output_size); - -+ if (internal_nrbytes) -+ XCRYPT_SECURE_MEMSET (internal_rbytes, internal_nrbytes); -+ - return output[0] == '*' ? 0 : output; - } - SYMVER_crypt_gensalt_rn; - -From 19ac122ea84b370e421a8cb5a174a64577f6fa4e Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 29 Jun 2018 02:59:42 +0000 -Subject: [PATCH 10/41] test-gensalt: extend checks of expected output - -In addition to checks for expected output length, -check expected output strings for deterministic methods. ---- - test-gensalt.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 83 insertions(+), 13 deletions(-) - -diff --git a/test-gensalt.c b/test-gensalt.c -index f4d0629..2705671 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -14,9 +14,72 @@ static const char *const entropy[] = - 0 - }; - -+#if ENABLE_WEAK_HASHES -+static const char *const des_expected_output[] = { "Mp", "Pp", "ZH", "Uh"}; -+static const char *const md5_expected_output[] = { -+ "$1$MJHnaAke", -+ "$1$PKXc3hCO", -+ "$1$ZAFlICwY", -+ "$1$UqGBkVu0" -+}; -+#if ENABLE_WEAK_NON_GLIBC_HASHES -+static const char *const bsdi_expected_output[] = { -+ "_J9..MJHn", -+ "_J9..PKXc", -+ "_J9..ZAFl", -+ "_J9..UqGB" -+}; -+static const char *const nthash_expected_output[] = { -+ "$3$__not_used__c809a450df09a3", -+ "$3$__not_used__30d0d6f834c0c3", -+ "$3$__not_used__0eeeebb83d6fe4", -+ "$3$__not_used__1c690d6a9ef88c" -+}; -+#define sunmd5_expected_output 0 /* output is not deterministic */ -+#define pbkdf_expected_output 0 /* output is not deterministic */ -+#endif -+#endif -+static const char *const sha256_expected_output[] = { -+ "$5$MJHnaAkegEVYHsFK", -+ "$5$PKXc3hCOSyMqdaEQ", -+ "$5$ZAFlICwYRETzIzIj", -+ "$5$UqGBkVu01rurVZqg" -+}; -+static const char *const sha512_expected_output[] = { -+ "$6$MJHnaAkegEVYHsFK", -+ "$6$PKXc3hCOSyMqdaEQ", -+ "$6$ZAFlICwYRETzIzIj", -+ "$6$UqGBkVu01rurVZqg" -+}; -+static const char *const bcrypt_a_expected_output[] = { -+ "$2a$05$UBVLHeMpJ/QQCv3XqJx8zO", -+ "$2a$05$kxUgPcrmlm9XoOjvxCyfP.", -+ "$2a$05$HPNDjKMRFdR7zC87CMSmA.", -+ "$2a$05$mAyzaIeJu41dWUkxEbn8hO" -+}; -+static const char *const bcrypt_b_expected_output[] = { -+ "$2b$05$UBVLHeMpJ/QQCv3XqJx8zO", -+ "$2b$05$kxUgPcrmlm9XoOjvxCyfP.", -+ "$2b$05$HPNDjKMRFdR7zC87CMSmA.", -+ "$2b$05$mAyzaIeJu41dWUkxEbn8hO" -+}; -+static const char *const bcrypt_x_expected_output[] = { -+ "$2x$05$UBVLHeMpJ/QQCv3XqJx8zO", -+ "$2x$05$kxUgPcrmlm9XoOjvxCyfP.", -+ "$2x$05$HPNDjKMRFdR7zC87CMSmA.", -+ "$2x$05$mAyzaIeJu41dWUkxEbn8hO" -+}; -+static const char *const bcrypt_y_expected_output[] = { -+ "$2y$05$UBVLHeMpJ/QQCv3XqJx8zO", -+ "$2y$05$kxUgPcrmlm9XoOjvxCyfP.", -+ "$2y$05$HPNDjKMRFdR7zC87CMSmA.", -+ "$2y$05$mAyzaIeJu41dWUkxEbn8hO" -+}; -+ - struct testcase - { - const char *prefix; -+ const char *const *expected_output; - unsigned int expected_len; - unsigned int expected_auto_len; - }; -@@ -24,22 +87,22 @@ struct testcase - static const struct testcase testcases[] = - { - #if ENABLE_WEAK_HASHES -- { "", 2, 0 }, // DES -- { "$1$", 11, 0 }, // MD5 -+ { "", des_expected_output, 2, 0 }, // DES -+ { "$1$", md5_expected_output, 11, 0 }, // MD5 - #if ENABLE_WEAK_NON_GLIBC_HASHES -- { "_", 9, 0 }, // BSDi extended DES -- { "$3$", 29, 0 }, // NTHASH -- { "$md5", 27, 0 }, // SUNMD5 -- { "$sha1", 34, 74 }, // PBKDF with SHA1 -+ { "_", bsdi_expected_output, 9, 0 }, // BSDi extended DES -+ { "$3$", nthash_expected_output, 29, 0 }, // NTHASH -+ { "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5 -+ { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1 - #endif - #endif -- { "$5$", 19, 0 }, // SHA-2-256 -- { "$6$", 19, 0 }, // SHA-2-512 -- { "$2a$", 29, 0 }, // bcrypt mode A -- { "$2b$", 29, 0 }, // bcrypt mode B -- { "$2x$", 29, 0 }, // bcrypt mode X -- { "$2y$", 29, 0 }, // bcrypt mode Y -- { 0, 0, 0 } -+ { "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256 -+ { "$6$", sha512_expected_output, 19, 0 }, // SHA-2-512 -+ { "$2a$", bcrypt_a_expected_output, 29, 0 }, // bcrypt mode A -+ { "$2b$", bcrypt_b_expected_output, 29, 0 }, // bcrypt mode B -+ { "$2x$", bcrypt_x_expected_output, 29, 0 }, // bcrypt mode X -+ { "$2y$", bcrypt_y_expected_output, 29, 0 }, // bcrypt mode Y -+ { 0, 0, 0, 0 } - }; - - int -@@ -97,6 +160,13 @@ main (void) - tcase->prefix, ent, salt); - status = 1; - } -+ else if (entropy[ent] && tcase->expected_output && -+ strcmp (salt, tcase->expected_output[ent])) -+ { -+ fprintf (stderr, "ERROR: %s/%u -> %s (expected %s)\n", -+ tcase->prefix, ent, salt, tcase->expected_output[ent]); -+ status = 1; -+ } - else - fprintf (stderr, " ok: %s/%u -> %s\n", - tcase->prefix, ent, salt); - -From 75dd1518c70d11093117e5c575cc2d7c121415f9 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Sat, 30 Jun 2018 12:26:41 +0000 -Subject: [PATCH 11/41] crypt_sha1_rn: fix memory leak - -Reported-by: Vitaly Chikunov ---- - crypt-pbkdf1-sha1.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index ac4f04a..e8427d5 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -218,6 +218,8 @@ crypt_sha1_rn (const char *phrase, const char *setting, - - /* Don't leave anything around in vm they could use. */ - XCRYPT_SECURE_MEMSET (scratch, s_size) -+ XCRYPT_SECURE_MEMSET (salt, sl) -+ free (salt); - } - - /* Modified excerpt from: - -From 86f386578f997a1039df42e26ff3f766ed09454b Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Sat, 30 Jun 2018 12:26:41 +0000 -Subject: [PATCH 12/41] gensalt_sha1_rn: fix read of random bytes out of bounds - -Reported-by: Vitaly Chikunov ---- - crypt-pbkdf1-sha1.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index e8427d5..b55d233 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -250,7 +250,8 @@ gensalt_sha1_rn (unsigned long count, - for (c = 0; (c * sizeof (unsigned long)) + sizeof (unsigned long) <= nrbytes && - (c * enclen) + enclen <= CRYPT_SHA1_SALT_LENGTH; ++c) - { -- memcpy (&encbuf, rbytes + (c * enclen), sizeof (unsigned long)); -+ memcpy (&encbuf, rbytes + (c * sizeof (unsigned long)), -+ sizeof (unsigned long)); - to64 (output + n + (c * enclen), encbuf, (int)enclen); - } - - -From fd45d0e95045b49a80a87bfa184fc9be90336779 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 29 Jun 2018 13:22:51 +0000 -Subject: [PATCH 13/41] .travis.yml: reduce flakyness - -Reduce false positives by wrapping network-related operations -into a loop. ---- - .travis.yml | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/.travis.yml b/.travis.yml -index c812e22..7e892b2 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -96,7 +96,7 @@ matrix: - - FCVER="latest" - - before_install: -- - docker pull fedora:$FCVER -+ - for i in `seq 0 99`; do docker pull fedora:$FCVER && i= && break || sleep 1; done; [ -z "$i" ] - - perl -pe 's/\$(\w+)/$ENV{$1}/g' .travis.env.in > travis.env - - docker run -t -d -P --env-file travis.env --name buildenv -v $HOME/.ccache:/root/.ccache -v $PWD:/opt/libxcrypt fedora:$FCVER /bin/sh -c "mkdir -p /opt/libxcrypt ; bash" - - docker exec -t buildenv /bin/sh -c "echo \"deltarpm=0\" >> /etc/dnf/dnf.conf" -@@ -104,12 +104,12 @@ before_install: - - docker exec -t buildenv /bin/sh -c "echo \"max_parallel_downloads=20\" >> /etc/dnf/dnf.conf" - - docker exec -t buildenv /bin/sh -c "echo \"\" >> /etc/dnf/dnf.conf" - - if [[ "$FCVER" == "rawhide" ]] ; then docker exec -t buildenv /bin/sh -c "cat /opt/libxcrypt/.travis.dnf.conf.rawhide_latest >> /etc/dnf/dnf.conf" ; fi -- - docker exec -t buildenv /bin/sh -c "dnf makecache" -- - docker exec -t buildenv /bin/sh -c "dnf -y upgrade" -- - docker exec -t buildenv /bin/sh -c "dnf -y groups install buildsys-build" -- - docker exec -t buildenv /bin/sh -c "dnf -y install libtool" -- - if [[ "$CC" == "clang" ]] ; then docker exec -t buildenv /bin/sh -c "dnf -y install clang" ; fi -- - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "dnf -y install '/usr/bin/git' '/usr/bin/lcov' '/usr/bin/pip3'" ; fi -+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf makecache && i= && break || sleep 1; done; [ -z "$i" ]' -+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y upgrade && i= && break || sleep 1; done; [ -z "$i" ]' -+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y groups install buildsys-build && i= && break || sleep 1; done; [ -z "$i" ]' -+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install libtool && i= && break || sleep 1; done; [ -z "$i" ]' -+ - if [[ "$CC" == "clang" ]] ; then docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install clang && i= && break || sleep 1; done; [ -z "$i" ]' ; fi -+ - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install '/usr/bin/git' '/usr/bin/lcov' '/usr/bin/pip3' && i= && break || sleep 1; done; [ -z "$i" ]' ; fi - - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "pip3 install codecov" ; fi - - before_script: - -From 1a51a81abc609c1a48edb2f4c0887e892e9e968f Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Wed, 4 Jul 2018 15:07:31 -0400 -Subject: [PATCH 14/41] Check in alg-des-tables.c, don't run gen-des-tables at - build time. - -This eliminates a whole bunch of dodgy logic from -Makefile.am (Automake doesn't fully comprehend the distinction between -CC and CC_FOR_BUILD) and will also make it easier to support enabling -and disabling of individual hashes without needing AM_CONDITIONALs for -each. ---- - .gitignore | 2 - - LICENSING | 6 +- - Makefile.am | 26 +- - alg-des-tables.c | 3844 ++++++++++++++++++++++++++++++++++++++++++++ - configure.ac | 1 - - gen-des-tables.c | 11 +- - m4/ax_prog_cc_for_build.m4 | 158 -- - 7 files changed, 3853 insertions(+), 195 deletions(-) - create mode 100644 alg-des-tables.c - delete mode 100644 m4/ax_prog_cc_for_build.m4 - -diff --git a/.gitignore b/.gitignore -index 3728add..5e998dd 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -42,8 +42,6 @@ - *.o - *.so - *.trs --/gen-des-tables --/alg-des-tables.c - /crypt.h - /crypt-symbol-vers.h - /libcrypt.map -diff --git a/LICENSING b/LICENSING -index ad5b4b5..b6f5168 100644 ---- a/LICENSING -+++ b/LICENSING -@@ -19,7 +19,8 @@ source tree. For specific licensing terms consult the files themselves. - test-crypt-badsalt, test-crypt-nonnull - - * Copyright David Burren et al.; 3-clause BSD: -- alg-des.h, alg-des.c, crypt-des.c, crypt-des-obsolete.c, gen-des-tables.c -+ alg-des.h, alg-des.c, alg-des-tables.c, -+ crypt-des.c, crypt-des-obsolete.c, gen-des-tables.c - - * Public domain, written by Solar Designer et al.: - alg-md4.h, alg-md4.c, crypt-bcrypt.c, crypt-gensalt.c, test-crypt-bcrypt.c -@@ -49,9 +50,6 @@ source tree. For specific licensing terms consult the files themselves. - GPL (v3 or later), with Autoconf exception: - m4/zw_automodern.m4, m4/zw_simple_warnings.m4 - -- * Copyright Paolo Bonzini; FSF all-permissive license for short files: -- m4/ax_prog_cc_for_build.m4 -- - * Copyright holders unknown, no statement of license (all of these - files are part of the testsuite and do not contribute to the - installed library or its headers): -diff --git a/Makefile.am b/Makefile.am -index c219bac..71fbd62 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -114,7 +114,7 @@ check_PROGRAMS = \ - - if ENABLE_WEAK_HASHES - libcrypt_la_SOURCES += \ -- crypt-des.c crypt-md5.c alg-des.c alg-md5.c -+ crypt-des.c crypt-md5.c alg-des.c alg-des-tables.c alg-md5.c - - if ENABLE_WEAK_NON_GLIBC_HASHES - libcrypt_la_SOURCES += \ -@@ -122,30 +122,6 @@ libcrypt_la_SOURCES += \ - alg-hmac-sha1.c alg-md4.c alg-sha1.c - endif - --nodist_libcrypt_la_SOURCES = \ -- alg-des-tables.c --CLEANFILES += alg-des-tables.c alg-des-tables.c.T -- --noinst_PROGRAMS = gen-des-tables -- --LINK_FOR_BUILD = $(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) \ -- $(LDFLAGS_FOR_BUILD) $(TARGET_ARCH_FOR_BUILD) -o $@ -- --gen-des-tables$(BUILD_EXEEXT): $(gen_des_tables_OBJECTS) -- @rm -f gen-des-tables$(BUILD_EXEEXT) -- $(AM_V_CCLD)$(LINK_FOR_BUILD) $(gen_des_tables_OBJECTS) $(gen_des_tables_LDADD) $(LIBS) --# suppress the built-in rule for --gen-des-tables$(EXEEXT): -- --$(gen_des_tables_OBJECTS) : CC=$(CC_FOR_BUILD) --$(gen_des_tables_OBJECTS) : CFLAGS=$(CFLAGS_FOR_BUILD) --$(gen_des_tables_OBJECTS) : CPPFLAGS=$(CPPFLAGS_FOR_BUILD) --$(gen_des_tables_OBJECTS) : AM_CFLAGS=$(WARN_CFLAGS_FOR_BUILD) -- --alg-des-tables.c: gen-des-tables -- $(AM_V_GEN)./gen-des-tables$(BUILD_EXEEXT) > alg-des-tables.c.T -- $(AM_V_at)mv -f alg-des-tables.c.T alg-des-tables.c -- - check_PROGRAMS += \ - test-alg-des test-alg-md5 test-crypt-des test-crypt-md5 \ - test-crypt-badsalt -diff --git a/alg-des-tables.c b/alg-des-tables.c -new file mode 100644 -index 0000000..0bf9c88 ---- /dev/null -+++ b/alg-des-tables.c -@@ -0,0 +1,3844 @@ -+/* -+ * FreeSec: libcrypt for NetBSD -+ * -+ * Copyright (c) 1994 David Burren -+ * All rights reserved. -+ * -+ * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet -+ * this file should now *only* export crypt(), in order to make -+ * binaries of libcrypt exportable from the USA -+ * -+ * Adapted for FreeBSD-4.0 by Mark R V Murray -+ * this file should now *only* export crypt_des(), in order to make -+ * a module that can be optionally included in libcrypt. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. 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. -+ * 3. Neither the name of the author nor the names of other contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. -+ * -+ * This is an original implementation of the DES and the crypt(3) interfaces -+ * by David Burren . -+ */ -+ -+/* -+ * The tables in this file were generated from a more compact -+ * representation of the DES S-boxes and P-boxes by the program -+ * gen-des-tables.c, which we no longer bother to run at build time. -+ */ -+ -+#include "crypt-port.h" -+#include "alg-des.h" -+ -+const uint8_t m_sbox[4][4096] = { -+ { -+ 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2, -+ 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea, -+ 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5, 0xe0, 0xed, 0xee, 0xe8, -+ 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2, -+ 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec, 0xe9, 0xe0, 0xe3, 0xe5, -+ 0xe2, 0xee, 0xef, 0xe9, 0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07, -+ 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e, 0x09, 0x0c, 0x07, 0x00, -+ 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05, -+ 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01, 0x0a, 0x03, 0x04, 0x0f, -+ 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c, -+ 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09, 0x4f, 0x43, 0x41, 0x4d, -+ 0x48, 0x44, 0x4e, 0x47, 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e, -+ 0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49, -+ 0x45, 0x4b, 0x4a, 0x45, 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41, -+ 0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46, -+ 0x4c, 0x47, 0x46, 0x4c, 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49, -+ 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7, 0xf6, 0xff, 0xfb, 0xf2, -+ 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa, -+ 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5, 0xf0, 0xfd, 0xfe, 0xf8, -+ 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2, -+ 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc, 0xf9, 0xf0, 0xf3, 0xf5, -+ 0xf2, 0xfe, 0xff, 0xf9, 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7, -+ 0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0, -+ 0xd2, 0xd1, 0xdd, 0xda, 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5, -+ 0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf, -+ 0xdd, 0xd4, 0xd1, 0xd2, 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc, -+ 0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9, 0x7f, 0x73, 0x71, 0x7d, -+ 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e, -+ 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a, 0x7c, 0x76, 0x70, 0x79, -+ 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71, -+ 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72, 0x75, 0x7b, 0x78, 0x76, -+ 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79, -+ 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17, 0x16, 0x1f, 0x1b, 0x12, -+ 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a, -+ 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15, 0x10, 0x1d, 0x1e, 0x18, -+ 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12, -+ 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c, 0x19, 0x10, 0x13, 0x15, -+ 0x12, 0x1e, 0x1f, 0x19, 0x4f, 0x43, 0x41, 0x4d, 0x48, 0x44, 0x4e, 0x47, -+ 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e, 0x49, 0x4c, 0x47, 0x40, -+ 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49, 0x45, 0x4b, 0x4a, 0x45, -+ 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41, 0x4a, 0x43, 0x44, 0x4f, -+ 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46, 0x4c, 0x47, 0x46, 0x4c, -+ 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49, 0x2f, 0x23, 0x21, 0x2d, -+ 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e, -+ 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a, 0x2c, 0x26, 0x20, 0x29, -+ 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21, -+ 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22, 0x25, 0x2b, 0x28, 0x26, -+ 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29, -+ 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2, -+ 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea, -+ 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5, 0xe0, 0xed, 0xee, 0xe8, -+ 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2, -+ 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec, 0xe9, 0xe0, 0xe3, 0xe5, -+ 0xe2, 0xee, 0xef, 0xe9, 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7, -+ 0xf6, 0xff, 0xfb, 0xf2, 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0, -+ 0xf2, 0xf1, 0xfd, 0xfa, 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5, -+ 0xf0, 0xfd, 0xfe, 0xf8, 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff, -+ 0xfd, 0xf4, 0xf1, 0xf2, 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc, -+ 0xf9, 0xf0, 0xf3, 0xf5, 0xf2, 0xfe, 0xff, 0xf9, 0x2f, 0x23, 0x21, 0x2d, -+ 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e, -+ 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a, 0x2c, 0x26, 0x20, 0x29, -+ 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21, -+ 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22, 0x25, 0x2b, 0x28, 0x26, -+ 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29, -+ 0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7, 0xb6, 0xbf, 0xbb, 0xb2, -+ 0xb3, 0xb8, 0xb4, 0xbe, 0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba, -+ 0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5, 0xb0, 0xbd, 0xbe, 0xb8, -+ 0xb7, 0xba, 0xbb, 0xb1, 0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2, -+ 0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc, 0xb9, 0xb0, 0xb3, 0xb5, -+ 0xb2, 0xbe, 0xbf, 0xb9, 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7, -+ 0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0, -+ 0xd2, 0xd1, 0xdd, 0xda, 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5, -+ 0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf, -+ 0xdd, 0xd4, 0xd1, 0xd2, 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc, -+ 0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9, 0x8f, 0x83, 0x81, 0x8d, -+ 0x88, 0x84, 0x8e, 0x87, 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e, -+ 0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89, -+ 0x85, 0x8b, 0x8a, 0x85, 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81, -+ 0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86, -+ 0x8c, 0x87, 0x86, 0x8c, 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89, -+ 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17, 0x16, 0x1f, 0x1b, 0x12, -+ 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a, -+ 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15, 0x10, 0x1d, 0x1e, 0x18, -+ 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12, -+ 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c, 0x19, 0x10, 0x13, 0x15, -+ 0x12, 0x1e, 0x1f, 0x19, 0x3f, 0x33, 0x31, 0x3d, 0x38, 0x34, 0x3e, 0x37, -+ 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e, 0x39, 0x3c, 0x37, 0x30, -+ 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39, 0x35, 0x3b, 0x3a, 0x35, -+ 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31, 0x3a, 0x33, 0x34, 0x3f, -+ 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36, 0x3c, 0x37, 0x36, 0x3c, -+ 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39, 0xaf, 0xa3, 0xa1, 0xad, -+ 0xa8, 0xa4, 0xae, 0xa7, 0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae, -+ 0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa, 0xac, 0xa6, 0xa0, 0xa9, -+ 0xa5, 0xab, 0xaa, 0xa5, 0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1, -+ 0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2, 0xa5, 0xab, 0xa8, 0xa6, -+ 0xac, 0xa7, 0xa6, 0xac, 0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9, -+ 0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7, 0xa6, 0xaf, 0xab, 0xa2, -+ 0xa3, 0xa8, 0xa4, 0xae, 0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa, -+ 0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5, 0xa0, 0xad, 0xae, 0xa8, -+ 0xa7, 0xaa, 0xab, 0xa1, 0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2, -+ 0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac, 0xa9, 0xa0, 0xa3, 0xa5, -+ 0xa2, 0xae, 0xaf, 0xa9, 0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67, -+ 0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e, 0x69, 0x6c, 0x67, 0x60, -+ 0x62, 0x61, 0x6d, 0x6a, 0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65, -+ 0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61, 0x6a, 0x63, 0x64, 0x6f, -+ 0x6d, 0x64, 0x61, 0x62, 0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c, -+ 0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69, 0x6f, 0x63, 0x61, 0x6d, -+ 0x68, 0x64, 0x6e, 0x67, 0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e, -+ 0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a, 0x6c, 0x66, 0x60, 0x69, -+ 0x65, 0x6b, 0x6a, 0x65, 0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61, -+ 0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62, 0x65, 0x6b, 0x68, 0x66, -+ 0x6c, 0x67, 0x66, 0x6c, 0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69, -+ 0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7, 0xc6, 0xcf, 0xcb, 0xc2, -+ 0xc3, 0xc8, 0xc4, 0xce, 0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca, -+ 0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5, 0xc0, 0xcd, 0xce, 0xc8, -+ 0xc7, 0xca, 0xcb, 0xc1, 0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2, -+ 0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc, 0xc9, 0xc0, 0xc3, 0xc5, -+ 0xc2, 0xce, 0xcf, 0xc9, 0xcf, 0xc3, 0xc1, 0xcd, 0xc8, 0xc4, 0xce, 0xc7, -+ 0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce, 0xc9, 0xcc, 0xc7, 0xc0, -+ 0xc2, 0xc1, 0xcd, 0xca, 0xcc, 0xc6, 0xc0, 0xc9, 0xc5, 0xcb, 0xca, 0xc5, -+ 0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1, 0xca, 0xc3, 0xc4, 0xcf, -+ 0xcd, 0xc4, 0xc1, 0xc2, 0xc5, 0xcb, 0xc8, 0xc6, 0xcc, 0xc7, 0xc6, 0xcc, -+ 0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9, 0xbf, 0xb3, 0xb1, 0xbd, -+ 0xb8, 0xb4, 0xbe, 0xb7, 0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe, -+ 0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba, 0xbc, 0xb6, 0xb0, 0xb9, -+ 0xb5, 0xbb, 0xba, 0xb5, 0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1, -+ 0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2, 0xb5, 0xbb, 0xb8, 0xb6, -+ 0xbc, 0xb7, 0xb6, 0xbc, 0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9, -+ 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57, 0x56, 0x5f, 0x5b, 0x52, -+ 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a, -+ 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55, 0x50, 0x5d, 0x5e, 0x58, -+ 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52, -+ 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c, 0x59, 0x50, 0x53, 0x55, -+ 0x52, 0x5e, 0x5f, 0x59, 0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97, -+ 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e, 0x99, 0x9c, 0x97, 0x90, -+ 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95, -+ 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91, 0x9a, 0x93, 0x94, 0x9f, -+ 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c, -+ 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99, 0x9f, 0x93, 0x91, 0x9d, -+ 0x98, 0x94, 0x9e, 0x97, 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e, -+ 0x99, 0x9c, 0x97, 0x90, 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99, -+ 0x95, 0x9b, 0x9a, 0x95, 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91, -+ 0x9a, 0x93, 0x94, 0x9f, 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96, -+ 0x9c, 0x97, 0x96, 0x9c, 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99, -+ 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57, 0x56, 0x5f, 0x5b, 0x52, -+ 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a, -+ 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55, 0x50, 0x5d, 0x5e, 0x58, -+ 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52, -+ 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c, 0x59, 0x50, 0x53, 0x55, -+ 0x52, 0x5e, 0x5f, 0x59, 0x0f, 0x03, 0x01, 0x0d, 0x08, 0x04, 0x0e, 0x07, -+ 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e, 0x09, 0x0c, 0x07, 0x00, -+ 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09, 0x05, 0x0b, 0x0a, 0x05, -+ 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01, 0x0a, 0x03, 0x04, 0x0f, -+ 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06, 0x0c, 0x07, 0x06, 0x0c, -+ 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09, 0x3f, 0x33, 0x31, 0x3d, -+ 0x38, 0x34, 0x3e, 0x37, 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e, -+ 0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39, -+ 0x35, 0x3b, 0x3a, 0x35, 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31, -+ 0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36, -+ 0x3c, 0x37, 0x36, 0x3c, 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39, -+ 0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72, -+ 0x73, 0x78, 0x74, 0x7e, 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a, -+ 0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78, -+ 0x77, 0x7a, 0x7b, 0x71, 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72, -+ 0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75, -+ 0x72, 0x7e, 0x7f, 0x79, 0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87, -+ 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e, 0x89, 0x8c, 0x87, 0x80, -+ 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85, -+ 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81, 0x8a, 0x83, 0x84, 0x8f, -+ 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c, -+ 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89, 0x4f, 0x43, 0x41, 0x4d, -+ 0x48, 0x44, 0x4e, 0x47, 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e, -+ 0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49, -+ 0x45, 0x4b, 0x4a, 0x45, 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41, -+ 0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46, -+ 0x4c, 0x47, 0x46, 0x4c, 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49, -+ 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7, 0xf6, 0xff, 0xfb, 0xf2, -+ 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa, -+ 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5, 0xf0, 0xfd, 0xfe, 0xf8, -+ 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2, -+ 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc, 0xf9, 0xf0, 0xf3, 0xf5, -+ 0xf2, 0xfe, 0xff, 0xf9, 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17, -+ 0x16, 0x1f, 0x1b, 0x12, 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10, -+ 0x12, 0x11, 0x1d, 0x1a, 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15, -+ 0x10, 0x1d, 0x1e, 0x18, 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f, -+ 0x1d, 0x14, 0x11, 0x12, 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c, -+ 0x19, 0x10, 0x13, 0x15, 0x12, 0x1e, 0x1f, 0x19, 0xcf, 0xc3, 0xc1, 0xcd, -+ 0xc8, 0xc4, 0xce, 0xc7, 0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce, -+ 0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca, 0xcc, 0xc6, 0xc0, 0xc9, -+ 0xc5, 0xcb, 0xca, 0xc5, 0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1, -+ 0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2, 0xc5, 0xcb, 0xc8, 0xc6, -+ 0xcc, 0xc7, 0xc6, 0xcc, 0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9, -+ 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2, -+ 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea, -+ 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5, 0xe0, 0xed, 0xee, 0xe8, -+ 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef, 0xed, 0xe4, 0xe1, 0xe2, -+ 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec, 0xe9, 0xe0, 0xe3, 0xe5, -+ 0xe2, 0xee, 0xef, 0xe9, 0x8f, 0x83, 0x81, 0x8d, 0x88, 0x84, 0x8e, 0x87, -+ 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e, 0x89, 0x8c, 0x87, 0x80, -+ 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89, 0x85, 0x8b, 0x8a, 0x85, -+ 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81, 0x8a, 0x83, 0x84, 0x8f, -+ 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86, 0x8c, 0x87, 0x86, 0x8c, -+ 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89, 0x8f, 0x83, 0x81, 0x8d, -+ 0x88, 0x84, 0x8e, 0x87, 0x86, 0x8f, 0x8b, 0x82, 0x83, 0x88, 0x84, 0x8e, -+ 0x89, 0x8c, 0x87, 0x80, 0x82, 0x81, 0x8d, 0x8a, 0x8c, 0x86, 0x80, 0x89, -+ 0x85, 0x8b, 0x8a, 0x85, 0x80, 0x8d, 0x8e, 0x88, 0x87, 0x8a, 0x8b, 0x81, -+ 0x8a, 0x83, 0x84, 0x8f, 0x8d, 0x84, 0x81, 0x82, 0x85, 0x8b, 0x88, 0x86, -+ 0x8c, 0x87, 0x86, 0x8c, 0x89, 0x80, 0x83, 0x85, 0x82, 0x8e, 0x8f, 0x89, -+ 0x2f, 0x23, 0x21, 0x2d, 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22, -+ 0x23, 0x28, 0x24, 0x2e, 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a, -+ 0x2c, 0x26, 0x20, 0x29, 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28, -+ 0x27, 0x2a, 0x2b, 0x21, 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22, -+ 0x25, 0x2b, 0x28, 0x26, 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25, -+ 0x22, 0x2e, 0x2f, 0x29, 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7, -+ 0xd6, 0xdf, 0xdb, 0xd2, 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0, -+ 0xd2, 0xd1, 0xdd, 0xda, 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5, -+ 0xd0, 0xdd, 0xde, 0xd8, 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf, -+ 0xdd, 0xd4, 0xd1, 0xd2, 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc, -+ 0xd9, 0xd0, 0xd3, 0xd5, 0xd2, 0xde, 0xdf, 0xd9, 0x4f, 0x43, 0x41, 0x4d, -+ 0x48, 0x44, 0x4e, 0x47, 0x46, 0x4f, 0x4b, 0x42, 0x43, 0x48, 0x44, 0x4e, -+ 0x49, 0x4c, 0x47, 0x40, 0x42, 0x41, 0x4d, 0x4a, 0x4c, 0x46, 0x40, 0x49, -+ 0x45, 0x4b, 0x4a, 0x45, 0x40, 0x4d, 0x4e, 0x48, 0x47, 0x4a, 0x4b, 0x41, -+ 0x4a, 0x43, 0x44, 0x4f, 0x4d, 0x44, 0x41, 0x42, 0x45, 0x4b, 0x48, 0x46, -+ 0x4c, 0x47, 0x46, 0x4c, 0x49, 0x40, 0x43, 0x45, 0x42, 0x4e, 0x4f, 0x49, -+ 0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67, 0x66, 0x6f, 0x6b, 0x62, -+ 0x63, 0x68, 0x64, 0x6e, 0x69, 0x6c, 0x67, 0x60, 0x62, 0x61, 0x6d, 0x6a, -+ 0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65, 0x60, 0x6d, 0x6e, 0x68, -+ 0x67, 0x6a, 0x6b, 0x61, 0x6a, 0x63, 0x64, 0x6f, 0x6d, 0x64, 0x61, 0x62, -+ 0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c, 0x69, 0x60, 0x63, 0x65, -+ 0x62, 0x6e, 0x6f, 0x69, 0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97, -+ 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e, 0x99, 0x9c, 0x97, 0x90, -+ 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95, -+ 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91, 0x9a, 0x93, 0x94, 0x9f, -+ 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c, -+ 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99, 0x2f, 0x23, 0x21, 0x2d, -+ 0x28, 0x24, 0x2e, 0x27, 0x26, 0x2f, 0x2b, 0x22, 0x23, 0x28, 0x24, 0x2e, -+ 0x29, 0x2c, 0x27, 0x20, 0x22, 0x21, 0x2d, 0x2a, 0x2c, 0x26, 0x20, 0x29, -+ 0x25, 0x2b, 0x2a, 0x25, 0x20, 0x2d, 0x2e, 0x28, 0x27, 0x2a, 0x2b, 0x21, -+ 0x2a, 0x23, 0x24, 0x2f, 0x2d, 0x24, 0x21, 0x22, 0x25, 0x2b, 0x28, 0x26, -+ 0x2c, 0x27, 0x26, 0x2c, 0x29, 0x20, 0x23, 0x25, 0x22, 0x2e, 0x2f, 0x29, -+ 0x1f, 0x13, 0x11, 0x1d, 0x18, 0x14, 0x1e, 0x17, 0x16, 0x1f, 0x1b, 0x12, -+ 0x13, 0x18, 0x14, 0x1e, 0x19, 0x1c, 0x17, 0x10, 0x12, 0x11, 0x1d, 0x1a, -+ 0x1c, 0x16, 0x10, 0x19, 0x15, 0x1b, 0x1a, 0x15, 0x10, 0x1d, 0x1e, 0x18, -+ 0x17, 0x1a, 0x1b, 0x11, 0x1a, 0x13, 0x14, 0x1f, 0x1d, 0x14, 0x11, 0x12, -+ 0x15, 0x1b, 0x18, 0x16, 0x1c, 0x17, 0x16, 0x1c, 0x19, 0x10, 0x13, 0x15, -+ 0x12, 0x1e, 0x1f, 0x19, 0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7, -+ 0xb6, 0xbf, 0xbb, 0xb2, 0xb3, 0xb8, 0xb4, 0xbe, 0xb9, 0xbc, 0xb7, 0xb0, -+ 0xb2, 0xb1, 0xbd, 0xba, 0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5, -+ 0xb0, 0xbd, 0xbe, 0xb8, 0xb7, 0xba, 0xbb, 0xb1, 0xba, 0xb3, 0xb4, 0xbf, -+ 0xbd, 0xb4, 0xb1, 0xb2, 0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc, -+ 0xb9, 0xb0, 0xb3, 0xb5, 0xb2, 0xbe, 0xbf, 0xb9, 0x7f, 0x73, 0x71, 0x7d, -+ 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72, 0x73, 0x78, 0x74, 0x7e, -+ 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a, 0x7c, 0x76, 0x70, 0x79, -+ 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78, 0x77, 0x7a, 0x7b, 0x71, -+ 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72, 0x75, 0x7b, 0x78, 0x76, -+ 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75, 0x72, 0x7e, 0x7f, 0x79, -+ 0xff, 0xf3, 0xf1, 0xfd, 0xf8, 0xf4, 0xfe, 0xf7, 0xf6, 0xff, 0xfb, 0xf2, -+ 0xf3, 0xf8, 0xf4, 0xfe, 0xf9, 0xfc, 0xf7, 0xf0, 0xf2, 0xf1, 0xfd, 0xfa, -+ 0xfc, 0xf6, 0xf0, 0xf9, 0xf5, 0xfb, 0xfa, 0xf5, 0xf0, 0xfd, 0xfe, 0xf8, -+ 0xf7, 0xfa, 0xfb, 0xf1, 0xfa, 0xf3, 0xf4, 0xff, 0xfd, 0xf4, 0xf1, 0xf2, -+ 0xf5, 0xfb, 0xf8, 0xf6, 0xfc, 0xf7, 0xf6, 0xfc, 0xf9, 0xf0, 0xf3, 0xf5, -+ 0xf2, 0xfe, 0xff, 0xf9, 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57, -+ 0x56, 0x5f, 0x5b, 0x52, 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50, -+ 0x52, 0x51, 0x5d, 0x5a, 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55, -+ 0x50, 0x5d, 0x5e, 0x58, 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f, -+ 0x5d, 0x54, 0x51, 0x52, 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c, -+ 0x59, 0x50, 0x53, 0x55, 0x52, 0x5e, 0x5f, 0x59, 0xcf, 0xc3, 0xc1, 0xcd, -+ 0xc8, 0xc4, 0xce, 0xc7, 0xc6, 0xcf, 0xcb, 0xc2, 0xc3, 0xc8, 0xc4, 0xce, -+ 0xc9, 0xcc, 0xc7, 0xc0, 0xc2, 0xc1, 0xcd, 0xca, 0xcc, 0xc6, 0xc0, 0xc9, -+ 0xc5, 0xcb, 0xca, 0xc5, 0xc0, 0xcd, 0xce, 0xc8, 0xc7, 0xca, 0xcb, 0xc1, -+ 0xca, 0xc3, 0xc4, 0xcf, 0xcd, 0xc4, 0xc1, 0xc2, 0xc5, 0xcb, 0xc8, 0xc6, -+ 0xcc, 0xc7, 0xc6, 0xcc, 0xc9, 0xc0, 0xc3, 0xc5, 0xc2, 0xce, 0xcf, 0xc9, -+ 0xbf, 0xb3, 0xb1, 0xbd, 0xb8, 0xb4, 0xbe, 0xb7, 0xb6, 0xbf, 0xbb, 0xb2, -+ 0xb3, 0xb8, 0xb4, 0xbe, 0xb9, 0xbc, 0xb7, 0xb0, 0xb2, 0xb1, 0xbd, 0xba, -+ 0xbc, 0xb6, 0xb0, 0xb9, 0xb5, 0xbb, 0xba, 0xb5, 0xb0, 0xbd, 0xbe, 0xb8, -+ 0xb7, 0xba, 0xbb, 0xb1, 0xba, 0xb3, 0xb4, 0xbf, 0xbd, 0xb4, 0xb1, 0xb2, -+ 0xb5, 0xbb, 0xb8, 0xb6, 0xbc, 0xb7, 0xb6, 0xbc, 0xb9, 0xb0, 0xb3, 0xb5, -+ 0xb2, 0xbe, 0xbf, 0xb9, 0x9f, 0x93, 0x91, 0x9d, 0x98, 0x94, 0x9e, 0x97, -+ 0x96, 0x9f, 0x9b, 0x92, 0x93, 0x98, 0x94, 0x9e, 0x99, 0x9c, 0x97, 0x90, -+ 0x92, 0x91, 0x9d, 0x9a, 0x9c, 0x96, 0x90, 0x99, 0x95, 0x9b, 0x9a, 0x95, -+ 0x90, 0x9d, 0x9e, 0x98, 0x97, 0x9a, 0x9b, 0x91, 0x9a, 0x93, 0x94, 0x9f, -+ 0x9d, 0x94, 0x91, 0x92, 0x95, 0x9b, 0x98, 0x96, 0x9c, 0x97, 0x96, 0x9c, -+ 0x99, 0x90, 0x93, 0x95, 0x92, 0x9e, 0x9f, 0x99, 0x3f, 0x33, 0x31, 0x3d, -+ 0x38, 0x34, 0x3e, 0x37, 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e, -+ 0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39, -+ 0x35, 0x3b, 0x3a, 0x35, 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31, -+ 0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36, -+ 0x3c, 0x37, 0x36, 0x3c, 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39, -+ 0x7f, 0x73, 0x71, 0x7d, 0x78, 0x74, 0x7e, 0x77, 0x76, 0x7f, 0x7b, 0x72, -+ 0x73, 0x78, 0x74, 0x7e, 0x79, 0x7c, 0x77, 0x70, 0x72, 0x71, 0x7d, 0x7a, -+ 0x7c, 0x76, 0x70, 0x79, 0x75, 0x7b, 0x7a, 0x75, 0x70, 0x7d, 0x7e, 0x78, -+ 0x77, 0x7a, 0x7b, 0x71, 0x7a, 0x73, 0x74, 0x7f, 0x7d, 0x74, 0x71, 0x72, -+ 0x75, 0x7b, 0x78, 0x76, 0x7c, 0x77, 0x76, 0x7c, 0x79, 0x70, 0x73, 0x75, -+ 0x72, 0x7e, 0x7f, 0x79, 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, -+ 0xe6, 0xef, 0xeb, 0xe2, 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, -+ 0xe2, 0xe1, 0xed, 0xea, 0xec, 0xe6, 0xe0, 0xe9, 0xe5, 0xeb, 0xea, 0xe5, -+ 0xe0, 0xed, 0xee, 0xe8, 0xe7, 0xea, 0xeb, 0xe1, 0xea, 0xe3, 0xe4, 0xef, -+ 0xed, 0xe4, 0xe1, 0xe2, 0xe5, 0xeb, 0xe8, 0xe6, 0xec, 0xe7, 0xe6, 0xec, -+ 0xe9, 0xe0, 0xe3, 0xe5, 0xe2, 0xee, 0xef, 0xe9, 0x3f, 0x33, 0x31, 0x3d, -+ 0x38, 0x34, 0x3e, 0x37, 0x36, 0x3f, 0x3b, 0x32, 0x33, 0x38, 0x34, 0x3e, -+ 0x39, 0x3c, 0x37, 0x30, 0x32, 0x31, 0x3d, 0x3a, 0x3c, 0x36, 0x30, 0x39, -+ 0x35, 0x3b, 0x3a, 0x35, 0x30, 0x3d, 0x3e, 0x38, 0x37, 0x3a, 0x3b, 0x31, -+ 0x3a, 0x33, 0x34, 0x3f, 0x3d, 0x34, 0x31, 0x32, 0x35, 0x3b, 0x38, 0x36, -+ 0x3c, 0x37, 0x36, 0x3c, 0x39, 0x30, 0x33, 0x35, 0x32, 0x3e, 0x3f, 0x39, -+ 0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7, 0xa6, 0xaf, 0xab, 0xa2, -+ 0xa3, 0xa8, 0xa4, 0xae, 0xa9, 0xac, 0xa7, 0xa0, 0xa2, 0xa1, 0xad, 0xaa, -+ 0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5, 0xa0, 0xad, 0xae, 0xa8, -+ 0xa7, 0xaa, 0xab, 0xa1, 0xaa, 0xa3, 0xa4, 0xaf, 0xad, 0xa4, 0xa1, 0xa2, -+ 0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac, 0xa9, 0xa0, 0xa3, 0xa5, -+ 0xa2, 0xae, 0xaf, 0xa9, 0xaf, 0xa3, 0xa1, 0xad, 0xa8, 0xa4, 0xae, 0xa7, -+ 0xa6, 0xaf, 0xab, 0xa2, 0xa3, 0xa8, 0xa4, 0xae, 0xa9, 0xac, 0xa7, 0xa0, -+ 0xa2, 0xa1, 0xad, 0xaa, 0xac, 0xa6, 0xa0, 0xa9, 0xa5, 0xab, 0xaa, 0xa5, -+ 0xa0, 0xad, 0xae, 0xa8, 0xa7, 0xaa, 0xab, 0xa1, 0xaa, 0xa3, 0xa4, 0xaf, -+ 0xad, 0xa4, 0xa1, 0xa2, 0xa5, 0xab, 0xa8, 0xa6, 0xac, 0xa7, 0xa6, 0xac, -+ 0xa9, 0xa0, 0xa3, 0xa5, 0xa2, 0xae, 0xaf, 0xa9, 0x0f, 0x03, 0x01, 0x0d, -+ 0x08, 0x04, 0x0e, 0x07, 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e, -+ 0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09, -+ 0x05, 0x0b, 0x0a, 0x05, 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01, -+ 0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06, -+ 0x0c, 0x07, 0x06, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09, -+ 0x5f, 0x53, 0x51, 0x5d, 0x58, 0x54, 0x5e, 0x57, 0x56, 0x5f, 0x5b, 0x52, -+ 0x53, 0x58, 0x54, 0x5e, 0x59, 0x5c, 0x57, 0x50, 0x52, 0x51, 0x5d, 0x5a, -+ 0x5c, 0x56, 0x50, 0x59, 0x55, 0x5b, 0x5a, 0x55, 0x50, 0x5d, 0x5e, 0x58, -+ 0x57, 0x5a, 0x5b, 0x51, 0x5a, 0x53, 0x54, 0x5f, 0x5d, 0x54, 0x51, 0x52, -+ 0x55, 0x5b, 0x58, 0x56, 0x5c, 0x57, 0x56, 0x5c, 0x59, 0x50, 0x53, 0x55, -+ 0x52, 0x5e, 0x5f, 0x59, 0x6f, 0x63, 0x61, 0x6d, 0x68, 0x64, 0x6e, 0x67, -+ 0x66, 0x6f, 0x6b, 0x62, 0x63, 0x68, 0x64, 0x6e, 0x69, 0x6c, 0x67, 0x60, -+ 0x62, 0x61, 0x6d, 0x6a, 0x6c, 0x66, 0x60, 0x69, 0x65, 0x6b, 0x6a, 0x65, -+ 0x60, 0x6d, 0x6e, 0x68, 0x67, 0x6a, 0x6b, 0x61, 0x6a, 0x63, 0x64, 0x6f, -+ 0x6d, 0x64, 0x61, 0x62, 0x65, 0x6b, 0x68, 0x66, 0x6c, 0x67, 0x66, 0x6c, -+ 0x69, 0x60, 0x63, 0x65, 0x62, 0x6e, 0x6f, 0x69, 0x0f, 0x03, 0x01, 0x0d, -+ 0x08, 0x04, 0x0e, 0x07, 0x06, 0x0f, 0x0b, 0x02, 0x03, 0x08, 0x04, 0x0e, -+ 0x09, 0x0c, 0x07, 0x00, 0x02, 0x01, 0x0d, 0x0a, 0x0c, 0x06, 0x00, 0x09, -+ 0x05, 0x0b, 0x0a, 0x05, 0x00, 0x0d, 0x0e, 0x08, 0x07, 0x0a, 0x0b, 0x01, -+ 0x0a, 0x03, 0x04, 0x0f, 0x0d, 0x04, 0x01, 0x02, 0x05, 0x0b, 0x08, 0x06, -+ 0x0c, 0x07, 0x06, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x02, 0x0e, 0x0f, 0x09, -+ 0xdf, 0xd3, 0xd1, 0xdd, 0xd8, 0xd4, 0xde, 0xd7, 0xd6, 0xdf, 0xdb, 0xd2, -+ 0xd3, 0xd8, 0xd4, 0xde, 0xd9, 0xdc, 0xd7, 0xd0, 0xd2, 0xd1, 0xdd, 0xda, -+ 0xdc, 0xd6, 0xd0, 0xd9, 0xd5, 0xdb, 0xda, 0xd5, 0xd0, 0xdd, 0xde, 0xd8, -+ 0xd7, 0xda, 0xdb, 0xd1, 0xda, 0xd3, 0xd4, 0xdf, 0xdd, 0xd4, 0xd1, 0xd2, -+ 0xd5, 0xdb, 0xd8, 0xd6, 0xdc, 0xd7, 0xd6, 0xdc, 0xd9, 0xd0, 0xd3, 0xd5, -+ 0xd2, 0xde, 0xdf, 0xd9, -+ }, -+ { -+ 0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5, 0xa0, 0xa6, 0xa6, 0xaf, -+ 0xa9, 0xa0, 0xaa, 0xa3, 0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac, -+ 0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9, 0xaa, 0xa3, 0xa6, 0xaf, -+ 0xa9, 0xa0, 0xa0, 0xa6, 0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8, -+ 0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab, 0xa5, 0xac, 0xa2, 0xa7, -+ 0xa8, 0xa2, 0xa4, 0xae, 0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5, -+ 0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3, 0xd1, 0xd4, 0xd2, 0xd7, -+ 0xd8, 0xd2, 0xd5, 0xdc, 0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9, -+ 0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6, 0xdc, 0xda, 0xdb, 0xd1, -+ 0xd7, 0xdd, 0xdd, 0xd8, 0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb, -+ 0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde, 0x07, 0x0d, 0x0d, 0x08, -+ 0x0e, 0x0b, 0x03, 0x05, 0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03, -+ 0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c, 0x0b, 0x01, 0x0c, 0x0a, -+ 0x04, 0x0e, 0x0f, 0x09, 0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06, -+ 0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08, 0x0f, 0x09, 0x01, 0x04, -+ 0x03, 0x05, 0x0e, 0x0b, 0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e, -+ 0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75, 0x70, 0x76, 0x76, 0x7f, -+ 0x79, 0x70, 0x7a, 0x73, 0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c, -+ 0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79, 0x7a, 0x73, 0x76, 0x7f, -+ 0x79, 0x70, 0x70, 0x76, 0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78, -+ 0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b, 0x75, 0x7c, 0x72, 0x77, -+ 0x78, 0x72, 0x74, 0x7e, 0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95, -+ 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93, 0x91, 0x94, 0x92, 0x97, -+ 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99, -+ 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96, 0x9c, 0x9a, 0x9b, 0x91, -+ 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b, -+ 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e, 0x07, 0x0d, 0x0d, 0x08, -+ 0x0e, 0x0b, 0x03, 0x05, 0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03, -+ 0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c, 0x0b, 0x01, 0x0c, 0x0a, -+ 0x04, 0x0e, 0x0f, 0x09, 0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06, -+ 0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08, 0x0f, 0x09, 0x01, 0x04, -+ 0x03, 0x05, 0x0e, 0x0b, 0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e, -+ 0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef, -+ 0xe9, 0xe0, 0xea, 0xe3, 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec, -+ 0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef, -+ 0xe9, 0xe0, 0xe0, 0xe6, 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8, -+ 0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7, -+ 0xe8, 0xe2, 0xe4, 0xee, 0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95, -+ 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93, 0x91, 0x94, 0x92, 0x97, -+ 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99, -+ 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96, 0x9c, 0x9a, 0x9b, 0x91, -+ 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b, -+ 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e, 0x67, 0x6d, 0x6d, 0x68, -+ 0x6e, 0x6b, 0x63, 0x65, 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63, -+ 0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a, -+ 0x64, 0x6e, 0x6f, 0x69, 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66, -+ 0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64, -+ 0x63, 0x65, 0x6e, 0x6b, 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e, -+ 0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35, 0x30, 0x36, 0x36, 0x3f, -+ 0x39, 0x30, 0x3a, 0x33, 0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c, -+ 0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39, 0x3a, 0x33, 0x36, 0x3f, -+ 0x39, 0x30, 0x30, 0x36, 0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38, -+ 0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b, 0x35, 0x3c, 0x32, 0x37, -+ 0x38, 0x32, 0x34, 0x3e, 0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35, -+ 0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33, 0x31, 0x34, 0x32, 0x37, -+ 0x38, 0x32, 0x35, 0x3c, 0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39, -+ 0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36, 0x3c, 0x3a, 0x3b, 0x31, -+ 0x37, 0x3d, 0x3d, 0x38, 0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b, -+ 0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e, 0x47, 0x4d, 0x4d, 0x48, -+ 0x4e, 0x4b, 0x43, 0x45, 0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43, -+ 0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c, 0x4b, 0x41, 0x4c, 0x4a, -+ 0x44, 0x4e, 0x4f, 0x49, 0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46, -+ 0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48, 0x4f, 0x49, 0x41, 0x44, -+ 0x43, 0x45, 0x4e, 0x4b, 0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e, -+ 0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff, -+ 0xf9, 0xf0, 0xfa, 0xf3, 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc, -+ 0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff, -+ 0xf9, 0xf0, 0xf0, 0xf6, 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8, -+ 0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7, -+ 0xf8, 0xf2, 0xf4, 0xfe, 0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65, -+ 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63, 0x61, 0x64, 0x62, 0x67, -+ 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69, -+ 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66, 0x6c, 0x6a, 0x6b, 0x61, -+ 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b, -+ 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e, 0x57, 0x5d, 0x5d, 0x58, -+ 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53, -+ 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c, 0x5b, 0x51, 0x5c, 0x5a, -+ 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56, -+ 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58, 0x5f, 0x59, 0x51, 0x54, -+ 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e, -+ 0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5, 0xa0, 0xa6, 0xa6, 0xaf, -+ 0xa9, 0xa0, 0xaa, 0xa3, 0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac, -+ 0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9, 0xaa, 0xa3, 0xa6, 0xaf, -+ 0xa9, 0xa0, 0xa0, 0xa6, 0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8, -+ 0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab, 0xa5, 0xac, 0xa2, 0xa7, -+ 0xa8, 0xa2, 0xa4, 0xae, 0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15, -+ 0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13, 0x11, 0x14, 0x12, 0x17, -+ 0x18, 0x12, 0x15, 0x1c, 0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19, -+ 0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16, 0x1c, 0x1a, 0x1b, 0x11, -+ 0x17, 0x1d, 0x1d, 0x18, 0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b, -+ 0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e, 0x27, 0x2d, 0x2d, 0x28, -+ 0x2e, 0x2b, 0x23, 0x25, 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23, -+ 0x21, 0x24, 0x22, 0x27, 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a, -+ 0x24, 0x2e, 0x2f, 0x29, 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26, -+ 0x2c, 0x2a, 0x2b, 0x21, 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24, -+ 0x23, 0x25, 0x2e, 0x2b, 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e, -+ 0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5, 0xd0, 0xd6, 0xd6, 0xdf, -+ 0xd9, 0xd0, 0xda, 0xd3, 0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc, -+ 0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9, 0xda, 0xd3, 0xd6, 0xdf, -+ 0xd9, 0xd0, 0xd0, 0xd6, 0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8, -+ 0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb, 0xd5, 0xdc, 0xd2, 0xd7, -+ 0xd8, 0xd2, 0xd4, 0xde, 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85, -+ 0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87, -+ 0x88, 0x82, 0x85, 0x8c, 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89, -+ 0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81, -+ 0x87, 0x8d, 0x8d, 0x88, 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b, -+ 0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e, 0xc7, 0xcd, 0xcd, 0xc8, -+ 0xce, 0xcb, 0xc3, 0xc5, 0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3, -+ 0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc, 0xcb, 0xc1, 0xcc, 0xca, -+ 0xc4, 0xce, 0xcf, 0xc9, 0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6, -+ 0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8, 0xcf, 0xc9, 0xc1, 0xc4, -+ 0xc3, 0xc5, 0xce, 0xcb, 0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce, -+ 0x57, 0x5d, 0x5d, 0x58, 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f, -+ 0x59, 0x50, 0x5a, 0x53, 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c, -+ 0x5b, 0x51, 0x5c, 0x5a, 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f, -+ 0x59, 0x50, 0x50, 0x56, 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58, -+ 0x5f, 0x59, 0x51, 0x54, 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57, -+ 0x58, 0x52, 0x54, 0x5e, 0x77, 0x7d, 0x7d, 0x78, 0x7e, 0x7b, 0x73, 0x75, -+ 0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73, 0x71, 0x74, 0x72, 0x77, -+ 0x78, 0x72, 0x75, 0x7c, 0x7b, 0x71, 0x7c, 0x7a, 0x74, 0x7e, 0x7f, 0x79, -+ 0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76, 0x7c, 0x7a, 0x7b, 0x71, -+ 0x77, 0x7d, 0x7d, 0x78, 0x7f, 0x79, 0x71, 0x74, 0x73, 0x75, 0x7e, 0x7b, -+ 0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e, 0xe7, 0xed, 0xed, 0xe8, -+ 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3, -+ 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec, 0xeb, 0xe1, 0xec, 0xea, -+ 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6, -+ 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8, 0xef, 0xe9, 0xe1, 0xe4, -+ 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee, -+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc, -+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8, -+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7, -+ 0xb8, 0xb2, 0xb4, 0xbe, 0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5, -+ 0xc0, 0xc6, 0xc6, 0xcf, 0xc9, 0xc0, 0xca, 0xc3, 0xc1, 0xc4, 0xc2, 0xc7, -+ 0xc8, 0xc2, 0xc5, 0xcc, 0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9, -+ 0xca, 0xc3, 0xc6, 0xcf, 0xc9, 0xc0, 0xc0, 0xc6, 0xcc, 0xca, 0xcb, 0xc1, -+ 0xc7, 0xcd, 0xcd, 0xc8, 0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb, -+ 0xc5, 0xcc, 0xc2, 0xc7, 0xc8, 0xc2, 0xc4, 0xce, 0x47, 0x4d, 0x4d, 0x48, -+ 0x4e, 0x4b, 0x43, 0x45, 0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43, -+ 0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c, 0x4b, 0x41, 0x4c, 0x4a, -+ 0x44, 0x4e, 0x4f, 0x49, 0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46, -+ 0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48, 0x4f, 0x49, 0x41, 0x44, -+ 0x43, 0x45, 0x4e, 0x4b, 0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e, -+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc, -+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8, -+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7, -+ 0xb8, 0xb2, 0xb4, 0xbe, 0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25, -+ 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23, 0x21, 0x24, 0x22, 0x27, -+ 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29, -+ 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26, 0x2c, 0x2a, 0x2b, 0x21, -+ 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b, -+ 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e, 0xf7, 0xfd, 0xfd, 0xf8, -+ 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff, 0xf9, 0xf0, 0xfa, 0xf3, -+ 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc, 0xfb, 0xf1, 0xfc, 0xfa, -+ 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff, 0xf9, 0xf0, 0xf0, 0xf6, -+ 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8, 0xff, 0xf9, 0xf1, 0xf4, -+ 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7, 0xf8, 0xf2, 0xf4, 0xfe, -+ 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85, 0x80, 0x86, 0x86, 0x8f, -+ 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c, -+ 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89, 0x8a, 0x83, 0x86, 0x8f, -+ 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88, -+ 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b, 0x85, 0x8c, 0x82, 0x87, -+ 0x88, 0x82, 0x84, 0x8e, 0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15, -+ 0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13, 0x11, 0x14, 0x12, 0x17, -+ 0x18, 0x12, 0x15, 0x1c, 0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19, -+ 0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16, 0x1c, 0x1a, 0x1b, 0x11, -+ 0x17, 0x1d, 0x1d, 0x18, 0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b, -+ 0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e, 0xd7, 0xdd, 0xdd, 0xd8, -+ 0xde, 0xdb, 0xd3, 0xd5, 0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3, -+ 0xd1, 0xd4, 0xd2, 0xd7, 0xd8, 0xd2, 0xd5, 0xdc, 0xdb, 0xd1, 0xdc, 0xda, -+ 0xd4, 0xde, 0xdf, 0xd9, 0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6, -+ 0xdc, 0xda, 0xdb, 0xd1, 0xd7, 0xdd, 0xdd, 0xd8, 0xdf, 0xd9, 0xd1, 0xd4, -+ 0xd3, 0xd5, 0xde, 0xdb, 0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde, -+ 0x17, 0x1d, 0x1d, 0x18, 0x1e, 0x1b, 0x13, 0x15, 0x10, 0x16, 0x16, 0x1f, -+ 0x19, 0x10, 0x1a, 0x13, 0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c, -+ 0x1b, 0x11, 0x1c, 0x1a, 0x14, 0x1e, 0x1f, 0x19, 0x1a, 0x13, 0x16, 0x1f, -+ 0x19, 0x10, 0x10, 0x16, 0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18, -+ 0x1f, 0x19, 0x11, 0x14, 0x13, 0x15, 0x1e, 0x1b, 0x15, 0x1c, 0x12, 0x17, -+ 0x18, 0x12, 0x14, 0x1e, 0x67, 0x6d, 0x6d, 0x68, 0x6e, 0x6b, 0x63, 0x65, -+ 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63, 0x61, 0x64, 0x62, 0x67, -+ 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a, 0x64, 0x6e, 0x6f, 0x69, -+ 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66, 0x6c, 0x6a, 0x6b, 0x61, -+ 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64, 0x63, 0x65, 0x6e, 0x6b, -+ 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e, 0xa7, 0xad, 0xad, 0xa8, -+ 0xae, 0xab, 0xa3, 0xa5, 0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3, -+ 0xa1, 0xa4, 0xa2, 0xa7, 0xa8, 0xa2, 0xa5, 0xac, 0xab, 0xa1, 0xac, 0xaa, -+ 0xa4, 0xae, 0xaf, 0xa9, 0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6, -+ 0xac, 0xaa, 0xab, 0xa1, 0xa7, 0xad, 0xad, 0xa8, 0xaf, 0xa9, 0xa1, 0xa4, -+ 0xa3, 0xa5, 0xae, 0xab, 0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae, -+ 0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45, 0x40, 0x46, 0x46, 0x4f, -+ 0x49, 0x40, 0x4a, 0x43, 0x41, 0x44, 0x42, 0x47, 0x48, 0x42, 0x45, 0x4c, -+ 0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49, 0x4a, 0x43, 0x46, 0x4f, -+ 0x49, 0x40, 0x40, 0x46, 0x4c, 0x4a, 0x4b, 0x41, 0x47, 0x4d, 0x4d, 0x48, -+ 0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b, 0x45, 0x4c, 0x42, 0x47, -+ 0x48, 0x42, 0x44, 0x4e, 0xd7, 0xdd, 0xdd, 0xd8, 0xde, 0xdb, 0xd3, 0xd5, -+ 0xd0, 0xd6, 0xd6, 0xdf, 0xd9, 0xd0, 0xda, 0xd3, 0xd1, 0xd4, 0xd2, 0xd7, -+ 0xd8, 0xd2, 0xd5, 0xdc, 0xdb, 0xd1, 0xdc, 0xda, 0xd4, 0xde, 0xdf, 0xd9, -+ 0xda, 0xd3, 0xd6, 0xdf, 0xd9, 0xd0, 0xd0, 0xd6, 0xdc, 0xda, 0xdb, 0xd1, -+ 0xd7, 0xdd, 0xdd, 0xd8, 0xdf, 0xd9, 0xd1, 0xd4, 0xd3, 0xd5, 0xde, 0xdb, -+ 0xd5, 0xdc, 0xd2, 0xd7, 0xd8, 0xd2, 0xd4, 0xde, 0x97, 0x9d, 0x9d, 0x98, -+ 0x9e, 0x9b, 0x93, 0x95, 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93, -+ 0x91, 0x94, 0x92, 0x97, 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a, -+ 0x94, 0x9e, 0x9f, 0x99, 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96, -+ 0x9c, 0x9a, 0x9b, 0x91, 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94, -+ 0x93, 0x95, 0x9e, 0x9b, 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e, -+ 0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05, 0x00, 0x06, 0x06, 0x0f, -+ 0x09, 0x00, 0x0a, 0x03, 0x01, 0x04, 0x02, 0x07, 0x08, 0x02, 0x05, 0x0c, -+ 0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09, 0x0a, 0x03, 0x06, 0x0f, -+ 0x09, 0x00, 0x00, 0x06, 0x0c, 0x0a, 0x0b, 0x01, 0x07, 0x0d, 0x0d, 0x08, -+ 0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b, 0x05, 0x0c, 0x02, 0x07, -+ 0x08, 0x02, 0x04, 0x0e, 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85, -+ 0x80, 0x86, 0x86, 0x8f, 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87, -+ 0x88, 0x82, 0x85, 0x8c, 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89, -+ 0x8a, 0x83, 0x86, 0x8f, 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81, -+ 0x87, 0x8d, 0x8d, 0x88, 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b, -+ 0x85, 0x8c, 0x82, 0x87, 0x88, 0x82, 0x84, 0x8e, 0x67, 0x6d, 0x6d, 0x68, -+ 0x6e, 0x6b, 0x63, 0x65, 0x60, 0x66, 0x66, 0x6f, 0x69, 0x60, 0x6a, 0x63, -+ 0x61, 0x64, 0x62, 0x67, 0x68, 0x62, 0x65, 0x6c, 0x6b, 0x61, 0x6c, 0x6a, -+ 0x64, 0x6e, 0x6f, 0x69, 0x6a, 0x63, 0x66, 0x6f, 0x69, 0x60, 0x60, 0x66, -+ 0x6c, 0x6a, 0x6b, 0x61, 0x67, 0x6d, 0x6d, 0x68, 0x6f, 0x69, 0x61, 0x64, -+ 0x63, 0x65, 0x6e, 0x6b, 0x65, 0x6c, 0x62, 0x67, 0x68, 0x62, 0x64, 0x6e, -+ 0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff, -+ 0xf9, 0xf0, 0xfa, 0xf3, 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc, -+ 0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff, -+ 0xf9, 0xf0, 0xf0, 0xf6, 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8, -+ 0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7, -+ 0xf8, 0xf2, 0xf4, 0xfe, 0x97, 0x9d, 0x9d, 0x98, 0x9e, 0x9b, 0x93, 0x95, -+ 0x90, 0x96, 0x96, 0x9f, 0x99, 0x90, 0x9a, 0x93, 0x91, 0x94, 0x92, 0x97, -+ 0x98, 0x92, 0x95, 0x9c, 0x9b, 0x91, 0x9c, 0x9a, 0x94, 0x9e, 0x9f, 0x99, -+ 0x9a, 0x93, 0x96, 0x9f, 0x99, 0x90, 0x90, 0x96, 0x9c, 0x9a, 0x9b, 0x91, -+ 0x97, 0x9d, 0x9d, 0x98, 0x9f, 0x99, 0x91, 0x94, 0x93, 0x95, 0x9e, 0x9b, -+ 0x95, 0x9c, 0x92, 0x97, 0x98, 0x92, 0x94, 0x9e, 0x37, 0x3d, 0x3d, 0x38, -+ 0x3e, 0x3b, 0x33, 0x35, 0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33, -+ 0x31, 0x34, 0x32, 0x37, 0x38, 0x32, 0x35, 0x3c, 0x3b, 0x31, 0x3c, 0x3a, -+ 0x34, 0x3e, 0x3f, 0x39, 0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36, -+ 0x3c, 0x3a, 0x3b, 0x31, 0x37, 0x3d, 0x3d, 0x38, 0x3f, 0x39, 0x31, 0x34, -+ 0x33, 0x35, 0x3e, 0x3b, 0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e, -+ 0x87, 0x8d, 0x8d, 0x88, 0x8e, 0x8b, 0x83, 0x85, 0x80, 0x86, 0x86, 0x8f, -+ 0x89, 0x80, 0x8a, 0x83, 0x81, 0x84, 0x82, 0x87, 0x88, 0x82, 0x85, 0x8c, -+ 0x8b, 0x81, 0x8c, 0x8a, 0x84, 0x8e, 0x8f, 0x89, 0x8a, 0x83, 0x86, 0x8f, -+ 0x89, 0x80, 0x80, 0x86, 0x8c, 0x8a, 0x8b, 0x81, 0x87, 0x8d, 0x8d, 0x88, -+ 0x8f, 0x89, 0x81, 0x84, 0x83, 0x85, 0x8e, 0x8b, 0x85, 0x8c, 0x82, 0x87, -+ 0x88, 0x82, 0x84, 0x8e, 0x07, 0x0d, 0x0d, 0x08, 0x0e, 0x0b, 0x03, 0x05, -+ 0x00, 0x06, 0x06, 0x0f, 0x09, 0x00, 0x0a, 0x03, 0x01, 0x04, 0x02, 0x07, -+ 0x08, 0x02, 0x05, 0x0c, 0x0b, 0x01, 0x0c, 0x0a, 0x04, 0x0e, 0x0f, 0x09, -+ 0x0a, 0x03, 0x06, 0x0f, 0x09, 0x00, 0x00, 0x06, 0x0c, 0x0a, 0x0b, 0x01, -+ 0x07, 0x0d, 0x0d, 0x08, 0x0f, 0x09, 0x01, 0x04, 0x03, 0x05, 0x0e, 0x0b, -+ 0x05, 0x0c, 0x02, 0x07, 0x08, 0x02, 0x04, 0x0e, 0x77, 0x7d, 0x7d, 0x78, -+ 0x7e, 0x7b, 0x73, 0x75, 0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73, -+ 0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c, 0x7b, 0x71, 0x7c, 0x7a, -+ 0x74, 0x7e, 0x7f, 0x79, 0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76, -+ 0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78, 0x7f, 0x79, 0x71, 0x74, -+ 0x73, 0x75, 0x7e, 0x7b, 0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e, -+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc, -+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8, -+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7, -+ 0xb8, 0xb2, 0xb4, 0xbe, 0x47, 0x4d, 0x4d, 0x48, 0x4e, 0x4b, 0x43, 0x45, -+ 0x40, 0x46, 0x46, 0x4f, 0x49, 0x40, 0x4a, 0x43, 0x41, 0x44, 0x42, 0x47, -+ 0x48, 0x42, 0x45, 0x4c, 0x4b, 0x41, 0x4c, 0x4a, 0x44, 0x4e, 0x4f, 0x49, -+ 0x4a, 0x43, 0x46, 0x4f, 0x49, 0x40, 0x40, 0x46, 0x4c, 0x4a, 0x4b, 0x41, -+ 0x47, 0x4d, 0x4d, 0x48, 0x4f, 0x49, 0x41, 0x44, 0x43, 0x45, 0x4e, 0x4b, -+ 0x45, 0x4c, 0x42, 0x47, 0x48, 0x42, 0x44, 0x4e, 0x17, 0x1d, 0x1d, 0x18, -+ 0x1e, 0x1b, 0x13, 0x15, 0x10, 0x16, 0x16, 0x1f, 0x19, 0x10, 0x1a, 0x13, -+ 0x11, 0x14, 0x12, 0x17, 0x18, 0x12, 0x15, 0x1c, 0x1b, 0x11, 0x1c, 0x1a, -+ 0x14, 0x1e, 0x1f, 0x19, 0x1a, 0x13, 0x16, 0x1f, 0x19, 0x10, 0x10, 0x16, -+ 0x1c, 0x1a, 0x1b, 0x11, 0x17, 0x1d, 0x1d, 0x18, 0x1f, 0x19, 0x11, 0x14, -+ 0x13, 0x15, 0x1e, 0x1b, 0x15, 0x1c, 0x12, 0x17, 0x18, 0x12, 0x14, 0x1e, -+ 0xf7, 0xfd, 0xfd, 0xf8, 0xfe, 0xfb, 0xf3, 0xf5, 0xf0, 0xf6, 0xf6, 0xff, -+ 0xf9, 0xf0, 0xfa, 0xf3, 0xf1, 0xf4, 0xf2, 0xf7, 0xf8, 0xf2, 0xf5, 0xfc, -+ 0xfb, 0xf1, 0xfc, 0xfa, 0xf4, 0xfe, 0xff, 0xf9, 0xfa, 0xf3, 0xf6, 0xff, -+ 0xf9, 0xf0, 0xf0, 0xf6, 0xfc, 0xfa, 0xfb, 0xf1, 0xf7, 0xfd, 0xfd, 0xf8, -+ 0xff, 0xf9, 0xf1, 0xf4, 0xf3, 0xf5, 0xfe, 0xfb, 0xf5, 0xfc, 0xf2, 0xf7, -+ 0xf8, 0xf2, 0xf4, 0xfe, 0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25, -+ 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23, 0x21, 0x24, 0x22, 0x27, -+ 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29, -+ 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26, 0x2c, 0x2a, 0x2b, 0x21, -+ 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b, -+ 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e, 0xe7, 0xed, 0xed, 0xe8, -+ 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef, 0xe9, 0xe0, 0xea, 0xe3, -+ 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec, 0xeb, 0xe1, 0xec, 0xea, -+ 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef, 0xe9, 0xe0, 0xe0, 0xe6, -+ 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8, 0xef, 0xe9, 0xe1, 0xe4, -+ 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7, 0xe8, 0xe2, 0xe4, 0xee, -+ 0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5, 0xc0, 0xc6, 0xc6, 0xcf, -+ 0xc9, 0xc0, 0xca, 0xc3, 0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc, -+ 0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9, 0xca, 0xc3, 0xc6, 0xcf, -+ 0xc9, 0xc0, 0xc0, 0xc6, 0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8, -+ 0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb, 0xc5, 0xcc, 0xc2, 0xc7, -+ 0xc8, 0xc2, 0xc4, 0xce, 0x37, 0x3d, 0x3d, 0x38, 0x3e, 0x3b, 0x33, 0x35, -+ 0x30, 0x36, 0x36, 0x3f, 0x39, 0x30, 0x3a, 0x33, 0x31, 0x34, 0x32, 0x37, -+ 0x38, 0x32, 0x35, 0x3c, 0x3b, 0x31, 0x3c, 0x3a, 0x34, 0x3e, 0x3f, 0x39, -+ 0x3a, 0x33, 0x36, 0x3f, 0x39, 0x30, 0x30, 0x36, 0x3c, 0x3a, 0x3b, 0x31, -+ 0x37, 0x3d, 0x3d, 0x38, 0x3f, 0x39, 0x31, 0x34, 0x33, 0x35, 0x3e, 0x3b, -+ 0x35, 0x3c, 0x32, 0x37, 0x38, 0x32, 0x34, 0x3e, 0x57, 0x5d, 0x5d, 0x58, -+ 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53, -+ 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c, 0x5b, 0x51, 0x5c, 0x5a, -+ 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56, -+ 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58, 0x5f, 0x59, 0x51, 0x54, -+ 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e, -+ 0xb7, 0xbd, 0xbd, 0xb8, 0xbe, 0xbb, 0xb3, 0xb5, 0xb0, 0xb6, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xba, 0xb3, 0xb1, 0xb4, 0xb2, 0xb7, 0xb8, 0xb2, 0xb5, 0xbc, -+ 0xbb, 0xb1, 0xbc, 0xba, 0xb4, 0xbe, 0xbf, 0xb9, 0xba, 0xb3, 0xb6, 0xbf, -+ 0xb9, 0xb0, 0xb0, 0xb6, 0xbc, 0xba, 0xbb, 0xb1, 0xb7, 0xbd, 0xbd, 0xb8, -+ 0xbf, 0xb9, 0xb1, 0xb4, 0xb3, 0xb5, 0xbe, 0xbb, 0xb5, 0xbc, 0xb2, 0xb7, -+ 0xb8, 0xb2, 0xb4, 0xbe, 0xa7, 0xad, 0xad, 0xa8, 0xae, 0xab, 0xa3, 0xa5, -+ 0xa0, 0xa6, 0xa6, 0xaf, 0xa9, 0xa0, 0xaa, 0xa3, 0xa1, 0xa4, 0xa2, 0xa7, -+ 0xa8, 0xa2, 0xa5, 0xac, 0xab, 0xa1, 0xac, 0xaa, 0xa4, 0xae, 0xaf, 0xa9, -+ 0xaa, 0xa3, 0xa6, 0xaf, 0xa9, 0xa0, 0xa0, 0xa6, 0xac, 0xaa, 0xab, 0xa1, -+ 0xa7, 0xad, 0xad, 0xa8, 0xaf, 0xa9, 0xa1, 0xa4, 0xa3, 0xa5, 0xae, 0xab, -+ 0xa5, 0xac, 0xa2, 0xa7, 0xa8, 0xa2, 0xa4, 0xae, 0x57, 0x5d, 0x5d, 0x58, -+ 0x5e, 0x5b, 0x53, 0x55, 0x50, 0x56, 0x56, 0x5f, 0x59, 0x50, 0x5a, 0x53, -+ 0x51, 0x54, 0x52, 0x57, 0x58, 0x52, 0x55, 0x5c, 0x5b, 0x51, 0x5c, 0x5a, -+ 0x54, 0x5e, 0x5f, 0x59, 0x5a, 0x53, 0x56, 0x5f, 0x59, 0x50, 0x50, 0x56, -+ 0x5c, 0x5a, 0x5b, 0x51, 0x57, 0x5d, 0x5d, 0x58, 0x5f, 0x59, 0x51, 0x54, -+ 0x53, 0x55, 0x5e, 0x5b, 0x55, 0x5c, 0x52, 0x57, 0x58, 0x52, 0x54, 0x5e, -+ 0xe7, 0xed, 0xed, 0xe8, 0xee, 0xeb, 0xe3, 0xe5, 0xe0, 0xe6, 0xe6, 0xef, -+ 0xe9, 0xe0, 0xea, 0xe3, 0xe1, 0xe4, 0xe2, 0xe7, 0xe8, 0xe2, 0xe5, 0xec, -+ 0xeb, 0xe1, 0xec, 0xea, 0xe4, 0xee, 0xef, 0xe9, 0xea, 0xe3, 0xe6, 0xef, -+ 0xe9, 0xe0, 0xe0, 0xe6, 0xec, 0xea, 0xeb, 0xe1, 0xe7, 0xed, 0xed, 0xe8, -+ 0xef, 0xe9, 0xe1, 0xe4, 0xe3, 0xe5, 0xee, 0xeb, 0xe5, 0xec, 0xe2, 0xe7, -+ 0xe8, 0xe2, 0xe4, 0xee, 0x27, 0x2d, 0x2d, 0x28, 0x2e, 0x2b, 0x23, 0x25, -+ 0x20, 0x26, 0x26, 0x2f, 0x29, 0x20, 0x2a, 0x23, 0x21, 0x24, 0x22, 0x27, -+ 0x28, 0x22, 0x25, 0x2c, 0x2b, 0x21, 0x2c, 0x2a, 0x24, 0x2e, 0x2f, 0x29, -+ 0x2a, 0x23, 0x26, 0x2f, 0x29, 0x20, 0x20, 0x26, 0x2c, 0x2a, 0x2b, 0x21, -+ 0x27, 0x2d, 0x2d, 0x28, 0x2f, 0x29, 0x21, 0x24, 0x23, 0x25, 0x2e, 0x2b, -+ 0x25, 0x2c, 0x22, 0x27, 0x28, 0x22, 0x24, 0x2e, 0x77, 0x7d, 0x7d, 0x78, -+ 0x7e, 0x7b, 0x73, 0x75, 0x70, 0x76, 0x76, 0x7f, 0x79, 0x70, 0x7a, 0x73, -+ 0x71, 0x74, 0x72, 0x77, 0x78, 0x72, 0x75, 0x7c, 0x7b, 0x71, 0x7c, 0x7a, -+ 0x74, 0x7e, 0x7f, 0x79, 0x7a, 0x73, 0x76, 0x7f, 0x79, 0x70, 0x70, 0x76, -+ 0x7c, 0x7a, 0x7b, 0x71, 0x77, 0x7d, 0x7d, 0x78, 0x7f, 0x79, 0x71, 0x74, -+ 0x73, 0x75, 0x7e, 0x7b, 0x75, 0x7c, 0x72, 0x77, 0x78, 0x72, 0x74, 0x7e, -+ 0xc7, 0xcd, 0xcd, 0xc8, 0xce, 0xcb, 0xc3, 0xc5, 0xc0, 0xc6, 0xc6, 0xcf, -+ 0xc9, 0xc0, 0xca, 0xc3, 0xc1, 0xc4, 0xc2, 0xc7, 0xc8, 0xc2, 0xc5, 0xcc, -+ 0xcb, 0xc1, 0xcc, 0xca, 0xc4, 0xce, 0xcf, 0xc9, 0xca, 0xc3, 0xc6, 0xcf, -+ 0xc9, 0xc0, 0xc0, 0xc6, 0xcc, 0xca, 0xcb, 0xc1, 0xc7, 0xcd, 0xcd, 0xc8, -+ 0xcf, 0xc9, 0xc1, 0xc4, 0xc3, 0xc5, 0xce, 0xcb, 0xc5, 0xcc, 0xc2, 0xc7, -+ 0xc8, 0xc2, 0xc4, 0xce, -+ }, -+ { -+ 0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22, 0x29, 0x27, 0x22, 0x2c, -+ 0x26, 0x29, 0x28, 0x25, 0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e, -+ 0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28, 0x29, 0x24, 0x2e, 0x23, -+ 0x2f, 0x22, 0x25, 0x2c, 0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a, -+ 0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27, 0x21, 0x26, 0x2d, 0x20, -+ 0x2b, 0x28, 0x26, 0x2d, 0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2, -+ 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5, 0xe0, 0xe6, 0xed, 0xe1, -+ 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8, -+ 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec, 0xe2, 0xe9, 0xe8, 0xe5, -+ 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7, -+ 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed, 0xcc, 0xca, 0xc1, 0xcf, -+ 0xca, 0xc4, 0xcf, 0xc2, 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5, -+ 0xc0, 0xc6, 0xcd, 0xc1, 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb, -+ 0xc5, 0xc3, 0xcb, 0xc8, 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc, -+ 0xc2, 0xc9, 0xc8, 0xc5, 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce, -+ 0xc4, 0xc1, 0xca, 0xc7, 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd, -+ 0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc, -+ 0xb6, 0xb9, 0xb8, 0xb5, 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe, -+ 0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3, -+ 0xbf, 0xb2, 0xb5, 0xbc, 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba, -+ 0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0, -+ 0xbb, 0xb8, 0xb6, 0xbd, 0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42, -+ 0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45, 0x40, 0x46, 0x4d, 0x41, -+ 0x43, 0x4d, 0x44, 0x4e, 0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48, -+ 0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c, 0x42, 0x49, 0x48, 0x45, -+ 0x4c, 0x4f, 0x43, 0x4a, 0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47, -+ 0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d, 0x2c, 0x2a, 0x21, 0x2f, -+ 0x2a, 0x24, 0x2f, 0x22, 0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25, -+ 0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e, 0x2e, 0x20, 0x27, 0x2b, -+ 0x25, 0x23, 0x2b, 0x28, 0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c, -+ 0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a, 0x27, 0x2b, 0x20, 0x2e, -+ 0x24, 0x21, 0x2a, 0x27, 0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d, -+ 0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c, -+ 0x16, 0x19, 0x18, 0x15, 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e, -+ 0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13, -+ 0x1f, 0x12, 0x15, 0x1c, 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a, -+ 0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10, -+ 0x1b, 0x18, 0x16, 0x1d, 0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2, -+ 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5, 0xc0, 0xc6, 0xcd, 0xc1, -+ 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8, -+ 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc, 0xc2, 0xc9, 0xc8, 0xc5, -+ 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7, -+ 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd, 0x7c, 0x7a, 0x71, 0x7f, -+ 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75, -+ 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e, 0x7e, 0x70, 0x77, 0x7b, -+ 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c, -+ 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a, 0x77, 0x7b, 0x70, 0x7e, -+ 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d, -+ 0x4c, 0x4a, 0x41, 0x4f, 0x4a, 0x44, 0x4f, 0x42, 0x49, 0x47, 0x42, 0x4c, -+ 0x46, 0x49, 0x48, 0x45, 0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e, -+ 0x4e, 0x40, 0x47, 0x4b, 0x45, 0x43, 0x4b, 0x48, 0x49, 0x44, 0x4e, 0x43, -+ 0x4f, 0x42, 0x45, 0x4c, 0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a, -+ 0x47, 0x4b, 0x40, 0x4e, 0x44, 0x41, 0x4a, 0x47, 0x41, 0x46, 0x4d, 0x40, -+ 0x4b, 0x48, 0x46, 0x4d, 0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2, -+ 0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5, 0xa0, 0xa6, 0xad, 0xa1, -+ 0xa3, 0xad, 0xa4, 0xae, 0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8, -+ 0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac, 0xa2, 0xa9, 0xa8, 0xa5, -+ 0xac, 0xaf, 0xa3, 0xaa, 0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7, -+ 0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad, 0x7c, 0x7a, 0x71, 0x7f, -+ 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75, -+ 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e, 0x7e, 0x70, 0x77, 0x7b, -+ 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c, -+ 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a, 0x77, 0x7b, 0x70, 0x7e, -+ 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d, -+ 0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc, -+ 0xb6, 0xb9, 0xb8, 0xb5, 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe, -+ 0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3, -+ 0xbf, 0xb2, 0xb5, 0xbc, 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba, -+ 0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0, -+ 0xbb, 0xb8, 0xb6, 0xbd, 0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2, -+ 0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5, 0xd0, 0xd6, 0xdd, 0xd1, -+ 0xd3, 0xdd, 0xd4, 0xde, 0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8, -+ 0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc, 0xd2, 0xd9, 0xd8, 0xd5, -+ 0xdc, 0xdf, 0xd3, 0xda, 0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7, -+ 0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd, 0x6c, 0x6a, 0x61, 0x6f, -+ 0x6a, 0x64, 0x6f, 0x62, 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65, -+ 0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b, -+ 0x65, 0x63, 0x6b, 0x68, 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c, -+ 0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e, -+ 0x64, 0x61, 0x6a, 0x67, 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d, -+ 0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c, -+ 0x16, 0x19, 0x18, 0x15, 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e, -+ 0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13, -+ 0x1f, 0x12, 0x15, 0x1c, 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a, -+ 0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10, -+ 0x1b, 0x18, 0x16, 0x1d, 0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82, -+ 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85, 0x80, 0x86, 0x8d, 0x81, -+ 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88, -+ 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c, 0x82, 0x89, 0x88, 0x85, -+ 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87, -+ 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d, 0x5c, 0x5a, 0x51, 0x5f, -+ 0x5a, 0x54, 0x5f, 0x52, 0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55, -+ 0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e, 0x5e, 0x50, 0x57, 0x5b, -+ 0x55, 0x53, 0x5b, 0x58, 0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c, -+ 0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a, 0x57, 0x5b, 0x50, 0x5e, -+ 0x54, 0x51, 0x5a, 0x57, 0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d, -+ 0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52, 0x59, 0x57, 0x52, 0x5c, -+ 0x56, 0x59, 0x58, 0x55, 0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e, -+ 0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58, 0x59, 0x54, 0x5e, 0x53, -+ 0x5f, 0x52, 0x55, 0x5c, 0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a, -+ 0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57, 0x51, 0x56, 0x5d, 0x50, -+ 0x5b, 0x58, 0x56, 0x5d, 0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02, -+ 0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05, 0x00, 0x06, 0x0d, 0x01, -+ 0x03, 0x0d, 0x04, 0x0e, 0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08, -+ 0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c, 0x02, 0x09, 0x08, 0x05, -+ 0x0c, 0x0f, 0x03, 0x0a, 0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07, -+ 0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d, 0x3c, 0x3a, 0x31, 0x3f, -+ 0x3a, 0x34, 0x3f, 0x32, 0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35, -+ 0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e, 0x3e, 0x30, 0x37, 0x3b, -+ 0x35, 0x33, 0x3b, 0x38, 0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c, -+ 0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a, 0x37, 0x3b, 0x30, 0x3e, -+ 0x34, 0x31, 0x3a, 0x37, 0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d, -+ 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2, 0xf9, 0xf7, 0xf2, 0xfc, -+ 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe, -+ 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8, 0xf9, 0xf4, 0xfe, 0xf3, -+ 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa, -+ 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7, 0xf1, 0xf6, 0xfd, 0xf0, -+ 0xfb, 0xf8, 0xf6, 0xfd, 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2, -+ 0xf9, 0xf7, 0xf2, 0xfc, 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1, -+ 0xf3, 0xfd, 0xf4, 0xfe, 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8, -+ 0xf9, 0xf4, 0xfe, 0xf3, 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5, -+ 0xfc, 0xff, 0xf3, 0xfa, 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7, -+ 0xf1, 0xf6, 0xfd, 0xf0, 0xfb, 0xf8, 0xf6, 0xfd, 0xac, 0xaa, 0xa1, 0xaf, -+ 0xaa, 0xa4, 0xaf, 0xa2, 0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5, -+ 0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae, 0xae, 0xa0, 0xa7, 0xab, -+ 0xa5, 0xa3, 0xab, 0xa8, 0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac, -+ 0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa, 0xa7, 0xab, 0xa0, 0xae, -+ 0xa4, 0xa1, 0xaa, 0xa7, 0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad, -+ 0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2, 0xd9, 0xd7, 0xd2, 0xdc, -+ 0xd6, 0xd9, 0xd8, 0xd5, 0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde, -+ 0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8, 0xd9, 0xd4, 0xde, 0xd3, -+ 0xdf, 0xd2, 0xd5, 0xdc, 0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda, -+ 0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7, 0xd1, 0xd6, 0xdd, 0xd0, -+ 0xdb, 0xd8, 0xd6, 0xdd, 0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32, -+ 0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35, 0x30, 0x36, 0x3d, 0x31, -+ 0x33, 0x3d, 0x34, 0x3e, 0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38, -+ 0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c, 0x32, 0x39, 0x38, 0x35, -+ 0x3c, 0x3f, 0x33, 0x3a, 0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37, -+ 0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d, 0x0c, 0x0a, 0x01, 0x0f, -+ 0x0a, 0x04, 0x0f, 0x02, 0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05, -+ 0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e, 0x0e, 0x00, 0x07, 0x0b, -+ 0x05, 0x03, 0x0b, 0x08, 0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c, -+ 0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a, 0x07, 0x0b, 0x00, 0x0e, -+ 0x04, 0x01, 0x0a, 0x07, 0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d, -+ 0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92, 0x99, 0x97, 0x92, 0x9c, -+ 0x96, 0x99, 0x98, 0x95, 0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e, -+ 0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98, 0x99, 0x94, 0x9e, 0x93, -+ 0x9f, 0x92, 0x95, 0x9c, 0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a, -+ 0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97, 0x91, 0x96, 0x9d, 0x90, -+ 0x9b, 0x98, 0x96, 0x9d, 0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2, -+ 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5, 0xe0, 0xe6, 0xed, 0xe1, -+ 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8, -+ 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec, 0xe2, 0xe9, 0xe8, 0xe5, -+ 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7, -+ 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed, 0x8c, 0x8a, 0x81, 0x8f, -+ 0x8a, 0x84, 0x8f, 0x82, 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85, -+ 0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b, -+ 0x85, 0x83, 0x8b, 0x88, 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c, -+ 0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e, -+ 0x84, 0x81, 0x8a, 0x87, 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d, -+ 0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92, 0x99, 0x97, 0x92, 0x9c, -+ 0x96, 0x99, 0x98, 0x95, 0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e, -+ 0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98, 0x99, 0x94, 0x9e, 0x93, -+ 0x9f, 0x92, 0x95, 0x9c, 0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a, -+ 0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97, 0x91, 0x96, 0x9d, 0x90, -+ 0x9b, 0x98, 0x96, 0x9d, 0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62, -+ 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65, 0x60, 0x66, 0x6d, 0x61, -+ 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68, -+ 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c, 0x62, 0x69, 0x68, 0x65, -+ 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67, -+ 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d, 0x4c, 0x4a, 0x41, 0x4f, -+ 0x4a, 0x44, 0x4f, 0x42, 0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45, -+ 0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e, 0x4e, 0x40, 0x47, 0x4b, -+ 0x45, 0x43, 0x4b, 0x48, 0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c, -+ 0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a, 0x47, 0x4b, 0x40, 0x4e, -+ 0x44, 0x41, 0x4a, 0x47, 0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d, -+ 0xbc, 0xba, 0xb1, 0xbf, 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc, -+ 0xb6, 0xb9, 0xb8, 0xb5, 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe, -+ 0xbe, 0xb0, 0xb7, 0xbb, 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3, -+ 0xbf, 0xb2, 0xb5, 0xbc, 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba, -+ 0xb7, 0xbb, 0xb0, 0xbe, 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0, -+ 0xbb, 0xb8, 0xb6, 0xbd, 0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22, -+ 0x29, 0x27, 0x22, 0x2c, 0x26, 0x29, 0x28, 0x25, 0x20, 0x26, 0x2d, 0x21, -+ 0x23, 0x2d, 0x24, 0x2e, 0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28, -+ 0x29, 0x24, 0x2e, 0x23, 0x2f, 0x22, 0x25, 0x2c, 0x22, 0x29, 0x28, 0x25, -+ 0x2c, 0x2f, 0x23, 0x2a, 0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27, -+ 0x21, 0x26, 0x2d, 0x20, 0x2b, 0x28, 0x26, 0x2d, 0x8c, 0x8a, 0x81, 0x8f, -+ 0x8a, 0x84, 0x8f, 0x82, 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85, -+ 0x80, 0x86, 0x8d, 0x81, 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b, -+ 0x85, 0x83, 0x8b, 0x88, 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c, -+ 0x82, 0x89, 0x88, 0x85, 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e, -+ 0x84, 0x81, 0x8a, 0x87, 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d, -+ 0x1c, 0x1a, 0x11, 0x1f, 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c, -+ 0x16, 0x19, 0x18, 0x15, 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e, -+ 0x1e, 0x10, 0x17, 0x1b, 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13, -+ 0x1f, 0x12, 0x15, 0x1c, 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a, -+ 0x17, 0x1b, 0x10, 0x1e, 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10, -+ 0x1b, 0x18, 0x16, 0x1d, 0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2, -+ 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5, 0xc0, 0xc6, 0xcd, 0xc1, -+ 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8, -+ 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc, 0xc2, 0xc9, 0xc8, 0xc5, -+ 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7, -+ 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd, 0xbc, 0xba, 0xb1, 0xbf, -+ 0xba, 0xb4, 0xbf, 0xb2, 0xb9, 0xb7, 0xb2, 0xbc, 0xb6, 0xb9, 0xb8, 0xb5, -+ 0xb0, 0xb6, 0xbd, 0xb1, 0xb3, 0xbd, 0xb4, 0xbe, 0xbe, 0xb0, 0xb7, 0xbb, -+ 0xb5, 0xb3, 0xbb, 0xb8, 0xb9, 0xb4, 0xbe, 0xb3, 0xbf, 0xb2, 0xb5, 0xbc, -+ 0xb2, 0xb9, 0xb8, 0xb5, 0xbc, 0xbf, 0xb3, 0xba, 0xb7, 0xbb, 0xb0, 0xbe, -+ 0xb4, 0xb1, 0xba, 0xb7, 0xb1, 0xb6, 0xbd, 0xb0, 0xbb, 0xb8, 0xb6, 0xbd, -+ 0x7c, 0x7a, 0x71, 0x7f, 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c, -+ 0x76, 0x79, 0x78, 0x75, 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e, -+ 0x7e, 0x70, 0x77, 0x7b, 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73, -+ 0x7f, 0x72, 0x75, 0x7c, 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a, -+ 0x77, 0x7b, 0x70, 0x7e, 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70, -+ 0x7b, 0x78, 0x76, 0x7d, 0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2, -+ 0xa9, 0xa7, 0xa2, 0xac, 0xa6, 0xa9, 0xa8, 0xa5, 0xa0, 0xa6, 0xad, 0xa1, -+ 0xa3, 0xad, 0xa4, 0xae, 0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8, -+ 0xa9, 0xa4, 0xae, 0xa3, 0xaf, 0xa2, 0xa5, 0xac, 0xa2, 0xa9, 0xa8, 0xa5, -+ 0xac, 0xaf, 0xa3, 0xaa, 0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7, -+ 0xa1, 0xa6, 0xad, 0xa0, 0xab, 0xa8, 0xa6, 0xad, 0x1c, 0x1a, 0x11, 0x1f, -+ 0x1a, 0x14, 0x1f, 0x12, 0x19, 0x17, 0x12, 0x1c, 0x16, 0x19, 0x18, 0x15, -+ 0x10, 0x16, 0x1d, 0x11, 0x13, 0x1d, 0x14, 0x1e, 0x1e, 0x10, 0x17, 0x1b, -+ 0x15, 0x13, 0x1b, 0x18, 0x19, 0x14, 0x1e, 0x13, 0x1f, 0x12, 0x15, 0x1c, -+ 0x12, 0x19, 0x18, 0x15, 0x1c, 0x1f, 0x13, 0x1a, 0x17, 0x1b, 0x10, 0x1e, -+ 0x14, 0x11, 0x1a, 0x17, 0x11, 0x16, 0x1d, 0x10, 0x1b, 0x18, 0x16, 0x1d, -+ 0xdc, 0xda, 0xd1, 0xdf, 0xda, 0xd4, 0xdf, 0xd2, 0xd9, 0xd7, 0xd2, 0xdc, -+ 0xd6, 0xd9, 0xd8, 0xd5, 0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde, -+ 0xde, 0xd0, 0xd7, 0xdb, 0xd5, 0xd3, 0xdb, 0xd8, 0xd9, 0xd4, 0xde, 0xd3, -+ 0xdf, 0xd2, 0xd5, 0xdc, 0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda, -+ 0xd7, 0xdb, 0xd0, 0xde, 0xd4, 0xd1, 0xda, 0xd7, 0xd1, 0xd6, 0xdd, 0xd0, -+ 0xdb, 0xd8, 0xd6, 0xdd, 0xec, 0xea, 0xe1, 0xef, 0xea, 0xe4, 0xef, 0xe2, -+ 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5, 0xe0, 0xe6, 0xed, 0xe1, -+ 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb, 0xe5, 0xe3, 0xeb, 0xe8, -+ 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec, 0xe2, 0xe9, 0xe8, 0xe5, -+ 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee, 0xe4, 0xe1, 0xea, 0xe7, -+ 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed, 0x7c, 0x7a, 0x71, 0x7f, -+ 0x7a, 0x74, 0x7f, 0x72, 0x79, 0x77, 0x72, 0x7c, 0x76, 0x79, 0x78, 0x75, -+ 0x70, 0x76, 0x7d, 0x71, 0x73, 0x7d, 0x74, 0x7e, 0x7e, 0x70, 0x77, 0x7b, -+ 0x75, 0x73, 0x7b, 0x78, 0x79, 0x74, 0x7e, 0x73, 0x7f, 0x72, 0x75, 0x7c, -+ 0x72, 0x79, 0x78, 0x75, 0x7c, 0x7f, 0x73, 0x7a, 0x77, 0x7b, 0x70, 0x7e, -+ 0x74, 0x71, 0x7a, 0x77, 0x71, 0x76, 0x7d, 0x70, 0x7b, 0x78, 0x76, 0x7d, -+ 0x2c, 0x2a, 0x21, 0x2f, 0x2a, 0x24, 0x2f, 0x22, 0x29, 0x27, 0x22, 0x2c, -+ 0x26, 0x29, 0x28, 0x25, 0x20, 0x26, 0x2d, 0x21, 0x23, 0x2d, 0x24, 0x2e, -+ 0x2e, 0x20, 0x27, 0x2b, 0x25, 0x23, 0x2b, 0x28, 0x29, 0x24, 0x2e, 0x23, -+ 0x2f, 0x22, 0x25, 0x2c, 0x22, 0x29, 0x28, 0x25, 0x2c, 0x2f, 0x23, 0x2a, -+ 0x27, 0x2b, 0x20, 0x2e, 0x24, 0x21, 0x2a, 0x27, 0x21, 0x26, 0x2d, 0x20, -+ 0x2b, 0x28, 0x26, 0x2d, 0x8c, 0x8a, 0x81, 0x8f, 0x8a, 0x84, 0x8f, 0x82, -+ 0x89, 0x87, 0x82, 0x8c, 0x86, 0x89, 0x88, 0x85, 0x80, 0x86, 0x8d, 0x81, -+ 0x83, 0x8d, 0x84, 0x8e, 0x8e, 0x80, 0x87, 0x8b, 0x85, 0x83, 0x8b, 0x88, -+ 0x89, 0x84, 0x8e, 0x83, 0x8f, 0x82, 0x85, 0x8c, 0x82, 0x89, 0x88, 0x85, -+ 0x8c, 0x8f, 0x83, 0x8a, 0x87, 0x8b, 0x80, 0x8e, 0x84, 0x81, 0x8a, 0x87, -+ 0x81, 0x86, 0x8d, 0x80, 0x8b, 0x88, 0x86, 0x8d, 0xdc, 0xda, 0xd1, 0xdf, -+ 0xda, 0xd4, 0xdf, 0xd2, 0xd9, 0xd7, 0xd2, 0xdc, 0xd6, 0xd9, 0xd8, 0xd5, -+ 0xd0, 0xd6, 0xdd, 0xd1, 0xd3, 0xdd, 0xd4, 0xde, 0xde, 0xd0, 0xd7, 0xdb, -+ 0xd5, 0xd3, 0xdb, 0xd8, 0xd9, 0xd4, 0xde, 0xd3, 0xdf, 0xd2, 0xd5, 0xdc, -+ 0xd2, 0xd9, 0xd8, 0xd5, 0xdc, 0xdf, 0xd3, 0xda, 0xd7, 0xdb, 0xd0, 0xde, -+ 0xd4, 0xd1, 0xda, 0xd7, 0xd1, 0xd6, 0xdd, 0xd0, 0xdb, 0xd8, 0xd6, 0xdd, -+ 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2, 0xf9, 0xf7, 0xf2, 0xfc, -+ 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe, -+ 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8, 0xf9, 0xf4, 0xfe, 0xf3, -+ 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa, -+ 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7, 0xf1, 0xf6, 0xfd, 0xf0, -+ 0xfb, 0xf8, 0xf6, 0xfd, 0x6c, 0x6a, 0x61, 0x6f, 0x6a, 0x64, 0x6f, 0x62, -+ 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65, 0x60, 0x66, 0x6d, 0x61, -+ 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b, 0x65, 0x63, 0x6b, 0x68, -+ 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c, 0x62, 0x69, 0x68, 0x65, -+ 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e, 0x64, 0x61, 0x6a, 0x67, -+ 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d, 0x9c, 0x9a, 0x91, 0x9f, -+ 0x9a, 0x94, 0x9f, 0x92, 0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95, -+ 0x90, 0x96, 0x9d, 0x91, 0x93, 0x9d, 0x94, 0x9e, 0x9e, 0x90, 0x97, 0x9b, -+ 0x95, 0x93, 0x9b, 0x98, 0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c, -+ 0x92, 0x99, 0x98, 0x95, 0x9c, 0x9f, 0x93, 0x9a, 0x97, 0x9b, 0x90, 0x9e, -+ 0x94, 0x91, 0x9a, 0x97, 0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d, -+ 0xfc, 0xfa, 0xf1, 0xff, 0xfa, 0xf4, 0xff, 0xf2, 0xf9, 0xf7, 0xf2, 0xfc, -+ 0xf6, 0xf9, 0xf8, 0xf5, 0xf0, 0xf6, 0xfd, 0xf1, 0xf3, 0xfd, 0xf4, 0xfe, -+ 0xfe, 0xf0, 0xf7, 0xfb, 0xf5, 0xf3, 0xfb, 0xf8, 0xf9, 0xf4, 0xfe, 0xf3, -+ 0xff, 0xf2, 0xf5, 0xfc, 0xf2, 0xf9, 0xf8, 0xf5, 0xfc, 0xff, 0xf3, 0xfa, -+ 0xf7, 0xfb, 0xf0, 0xfe, 0xf4, 0xf1, 0xfa, 0xf7, 0xf1, 0xf6, 0xfd, 0xf0, -+ 0xfb, 0xf8, 0xf6, 0xfd, 0xcc, 0xca, 0xc1, 0xcf, 0xca, 0xc4, 0xcf, 0xc2, -+ 0xc9, 0xc7, 0xc2, 0xcc, 0xc6, 0xc9, 0xc8, 0xc5, 0xc0, 0xc6, 0xcd, 0xc1, -+ 0xc3, 0xcd, 0xc4, 0xce, 0xce, 0xc0, 0xc7, 0xcb, 0xc5, 0xc3, 0xcb, 0xc8, -+ 0xc9, 0xc4, 0xce, 0xc3, 0xcf, 0xc2, 0xc5, 0xcc, 0xc2, 0xc9, 0xc8, 0xc5, -+ 0xcc, 0xcf, 0xc3, 0xca, 0xc7, 0xcb, 0xc0, 0xce, 0xc4, 0xc1, 0xca, 0xc7, -+ 0xc1, 0xc6, 0xcd, 0xc0, 0xcb, 0xc8, 0xc6, 0xcd, 0x0c, 0x0a, 0x01, 0x0f, -+ 0x0a, 0x04, 0x0f, 0x02, 0x09, 0x07, 0x02, 0x0c, 0x06, 0x09, 0x08, 0x05, -+ 0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e, 0x0e, 0x00, 0x07, 0x0b, -+ 0x05, 0x03, 0x0b, 0x08, 0x09, 0x04, 0x0e, 0x03, 0x0f, 0x02, 0x05, 0x0c, -+ 0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a, 0x07, 0x0b, 0x00, 0x0e, -+ 0x04, 0x01, 0x0a, 0x07, 0x01, 0x06, 0x0d, 0x00, 0x0b, 0x08, 0x06, 0x0d, -+ 0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52, 0x59, 0x57, 0x52, 0x5c, -+ 0x56, 0x59, 0x58, 0x55, 0x50, 0x56, 0x5d, 0x51, 0x53, 0x5d, 0x54, 0x5e, -+ 0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58, 0x59, 0x54, 0x5e, 0x53, -+ 0x5f, 0x52, 0x55, 0x5c, 0x52, 0x59, 0x58, 0x55, 0x5c, 0x5f, 0x53, 0x5a, -+ 0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57, 0x51, 0x56, 0x5d, 0x50, -+ 0x5b, 0x58, 0x56, 0x5d, 0x9c, 0x9a, 0x91, 0x9f, 0x9a, 0x94, 0x9f, 0x92, -+ 0x99, 0x97, 0x92, 0x9c, 0x96, 0x99, 0x98, 0x95, 0x90, 0x96, 0x9d, 0x91, -+ 0x93, 0x9d, 0x94, 0x9e, 0x9e, 0x90, 0x97, 0x9b, 0x95, 0x93, 0x9b, 0x98, -+ 0x99, 0x94, 0x9e, 0x93, 0x9f, 0x92, 0x95, 0x9c, 0x92, 0x99, 0x98, 0x95, -+ 0x9c, 0x9f, 0x93, 0x9a, 0x97, 0x9b, 0x90, 0x9e, 0x94, 0x91, 0x9a, 0x97, -+ 0x91, 0x96, 0x9d, 0x90, 0x9b, 0x98, 0x96, 0x9d, 0x6c, 0x6a, 0x61, 0x6f, -+ 0x6a, 0x64, 0x6f, 0x62, 0x69, 0x67, 0x62, 0x6c, 0x66, 0x69, 0x68, 0x65, -+ 0x60, 0x66, 0x6d, 0x61, 0x63, 0x6d, 0x64, 0x6e, 0x6e, 0x60, 0x67, 0x6b, -+ 0x65, 0x63, 0x6b, 0x68, 0x69, 0x64, 0x6e, 0x63, 0x6f, 0x62, 0x65, 0x6c, -+ 0x62, 0x69, 0x68, 0x65, 0x6c, 0x6f, 0x63, 0x6a, 0x67, 0x6b, 0x60, 0x6e, -+ 0x64, 0x61, 0x6a, 0x67, 0x61, 0x66, 0x6d, 0x60, 0x6b, 0x68, 0x66, 0x6d, -+ 0xac, 0xaa, 0xa1, 0xaf, 0xaa, 0xa4, 0xaf, 0xa2, 0xa9, 0xa7, 0xa2, 0xac, -+ 0xa6, 0xa9, 0xa8, 0xa5, 0xa0, 0xa6, 0xad, 0xa1, 0xa3, 0xad, 0xa4, 0xae, -+ 0xae, 0xa0, 0xa7, 0xab, 0xa5, 0xa3, 0xab, 0xa8, 0xa9, 0xa4, 0xae, 0xa3, -+ 0xaf, 0xa2, 0xa5, 0xac, 0xa2, 0xa9, 0xa8, 0xa5, 0xac, 0xaf, 0xa3, 0xaa, -+ 0xa7, 0xab, 0xa0, 0xae, 0xa4, 0xa1, 0xaa, 0xa7, 0xa1, 0xa6, 0xad, 0xa0, -+ 0xab, 0xa8, 0xa6, 0xad, 0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32, -+ 0x39, 0x37, 0x32, 0x3c, 0x36, 0x39, 0x38, 0x35, 0x30, 0x36, 0x3d, 0x31, -+ 0x33, 0x3d, 0x34, 0x3e, 0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38, -+ 0x39, 0x34, 0x3e, 0x33, 0x3f, 0x32, 0x35, 0x3c, 0x32, 0x39, 0x38, 0x35, -+ 0x3c, 0x3f, 0x33, 0x3a, 0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37, -+ 0x31, 0x36, 0x3d, 0x30, 0x3b, 0x38, 0x36, 0x3d, 0x4c, 0x4a, 0x41, 0x4f, -+ 0x4a, 0x44, 0x4f, 0x42, 0x49, 0x47, 0x42, 0x4c, 0x46, 0x49, 0x48, 0x45, -+ 0x40, 0x46, 0x4d, 0x41, 0x43, 0x4d, 0x44, 0x4e, 0x4e, 0x40, 0x47, 0x4b, -+ 0x45, 0x43, 0x4b, 0x48, 0x49, 0x44, 0x4e, 0x43, 0x4f, 0x42, 0x45, 0x4c, -+ 0x42, 0x49, 0x48, 0x45, 0x4c, 0x4f, 0x43, 0x4a, 0x47, 0x4b, 0x40, 0x4e, -+ 0x44, 0x41, 0x4a, 0x47, 0x41, 0x46, 0x4d, 0x40, 0x4b, 0x48, 0x46, 0x4d, -+ 0x0c, 0x0a, 0x01, 0x0f, 0x0a, 0x04, 0x0f, 0x02, 0x09, 0x07, 0x02, 0x0c, -+ 0x06, 0x09, 0x08, 0x05, 0x00, 0x06, 0x0d, 0x01, 0x03, 0x0d, 0x04, 0x0e, -+ 0x0e, 0x00, 0x07, 0x0b, 0x05, 0x03, 0x0b, 0x08, 0x09, 0x04, 0x0e, 0x03, -+ 0x0f, 0x02, 0x05, 0x0c, 0x02, 0x09, 0x08, 0x05, 0x0c, 0x0f, 0x03, 0x0a, -+ 0x07, 0x0b, 0x00, 0x0e, 0x04, 0x01, 0x0a, 0x07, 0x01, 0x06, 0x0d, 0x00, -+ 0x0b, 0x08, 0x06, 0x0d, 0x5c, 0x5a, 0x51, 0x5f, 0x5a, 0x54, 0x5f, 0x52, -+ 0x59, 0x57, 0x52, 0x5c, 0x56, 0x59, 0x58, 0x55, 0x50, 0x56, 0x5d, 0x51, -+ 0x53, 0x5d, 0x54, 0x5e, 0x5e, 0x50, 0x57, 0x5b, 0x55, 0x53, 0x5b, 0x58, -+ 0x59, 0x54, 0x5e, 0x53, 0x5f, 0x52, 0x55, 0x5c, 0x52, 0x59, 0x58, 0x55, -+ 0x5c, 0x5f, 0x53, 0x5a, 0x57, 0x5b, 0x50, 0x5e, 0x54, 0x51, 0x5a, 0x57, -+ 0x51, 0x56, 0x5d, 0x50, 0x5b, 0x58, 0x56, 0x5d, 0xec, 0xea, 0xe1, 0xef, -+ 0xea, 0xe4, 0xef, 0xe2, 0xe9, 0xe7, 0xe2, 0xec, 0xe6, 0xe9, 0xe8, 0xe5, -+ 0xe0, 0xe6, 0xed, 0xe1, 0xe3, 0xed, 0xe4, 0xee, 0xee, 0xe0, 0xe7, 0xeb, -+ 0xe5, 0xe3, 0xeb, 0xe8, 0xe9, 0xe4, 0xee, 0xe3, 0xef, 0xe2, 0xe5, 0xec, -+ 0xe2, 0xe9, 0xe8, 0xe5, 0xec, 0xef, 0xe3, 0xea, 0xe7, 0xeb, 0xe0, 0xee, -+ 0xe4, 0xe1, 0xea, 0xe7, 0xe1, 0xe6, 0xed, 0xe0, 0xeb, 0xe8, 0xe6, 0xed, -+ 0x3c, 0x3a, 0x31, 0x3f, 0x3a, 0x34, 0x3f, 0x32, 0x39, 0x37, 0x32, 0x3c, -+ 0x36, 0x39, 0x38, 0x35, 0x30, 0x36, 0x3d, 0x31, 0x33, 0x3d, 0x34, 0x3e, -+ 0x3e, 0x30, 0x37, 0x3b, 0x35, 0x33, 0x3b, 0x38, 0x39, 0x34, 0x3e, 0x33, -+ 0x3f, 0x32, 0x35, 0x3c, 0x32, 0x39, 0x38, 0x35, 0x3c, 0x3f, 0x33, 0x3a, -+ 0x37, 0x3b, 0x30, 0x3e, 0x34, 0x31, 0x3a, 0x37, 0x31, 0x36, 0x3d, 0x30, -+ 0x3b, 0x38, 0x36, 0x3d, -+ }, -+ { -+ 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48, 0x46, 0x4a, 0x4f, 0x43, -+ 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b, -+ 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42, 0x47, 0x42, 0x4b, 0x41, -+ 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d, -+ 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40, 0x4f, 0x43, 0x43, 0x45, -+ 0x45, 0x46, 0x48, 0x4b, 0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8, -+ 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4, 0xda, 0xdc, 0xd9, 0xd5, -+ 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2, -+ 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7, 0xd9, 0xd4, 0xdc, 0xda, -+ 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0, -+ 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb, 0xbd, 0xb1, 0xb2, 0xbf, -+ 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4, -+ 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb, 0xb5, 0xb0, 0xb0, 0xbe, -+ 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7, -+ 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd, 0xb0, 0xbf, 0xb6, 0xbc, -+ 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb, -+ 0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08, 0x06, 0x0a, 0x0f, 0x03, -+ 0x0b, 0x07, 0x01, 0x04, 0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b, -+ 0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02, 0x07, 0x02, 0x0b, 0x01, -+ 0x04, 0x0e, 0x01, 0x07, 0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d, -+ 0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00, 0x0f, 0x03, 0x03, 0x05, -+ 0x05, 0x06, 0x08, 0x0b, 0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28, -+ 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24, 0x2a, 0x2c, 0x29, 0x25, -+ 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22, -+ 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27, 0x29, 0x24, 0x2c, 0x2a, -+ 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20, -+ 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b, 0xbd, 0xb1, 0xb2, 0xbf, -+ 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4, -+ 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb, 0xb5, 0xb0, 0xb0, 0xbe, -+ 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7, -+ 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd, 0xb0, 0xbf, 0xb6, 0xbc, -+ 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb, -+ 0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8, 0xe6, 0xea, 0xef, 0xe3, -+ 0xeb, 0xe7, 0xe1, 0xe4, 0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb, -+ 0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2, 0xe7, 0xe2, 0xeb, 0xe1, -+ 0xe4, 0xee, 0xe1, 0xe7, 0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed, -+ 0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0, 0xef, 0xe3, 0xe3, 0xe5, -+ 0xe5, 0xe6, 0xe8, 0xeb, 0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78, -+ 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74, 0x7a, 0x7c, 0x79, 0x75, -+ 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72, -+ 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77, 0x79, 0x74, 0x7c, 0x7a, -+ 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70, -+ 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b, 0xfd, 0xf1, 0xf2, 0xff, -+ 0xf8, 0xfd, 0xf4, 0xf8, 0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4, -+ 0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb, 0xf5, 0xf0, 0xf0, 0xfe, -+ 0xfc, 0xf9, 0xf7, 0xf2, 0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7, -+ 0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd, 0xf0, 0xff, 0xf6, 0xfc, -+ 0xfa, 0xf9, 0xfd, 0xf0, 0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb, -+ 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48, 0x46, 0x4a, 0x4f, 0x43, -+ 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45, 0x43, 0x46, 0x4e, 0x4b, -+ 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42, 0x47, 0x42, 0x4b, 0x41, -+ 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a, 0x4e, 0x48, 0x42, 0x4d, -+ 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40, 0x4f, 0x43, 0x43, 0x45, -+ 0x45, 0x46, 0x48, 0x4b, 0x0d, 0x01, 0x02, 0x0f, 0x08, 0x0d, 0x04, 0x08, -+ 0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04, 0x0a, 0x0c, 0x09, 0x05, -+ 0x03, 0x06, 0x0e, 0x0b, 0x05, 0x00, 0x00, 0x0e, 0x0c, 0x09, 0x07, 0x02, -+ 0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07, 0x09, 0x04, 0x0c, 0x0a, -+ 0x0e, 0x08, 0x02, 0x0d, 0x00, 0x0f, 0x06, 0x0c, 0x0a, 0x09, 0x0d, 0x00, -+ 0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b, 0x9d, 0x91, 0x92, 0x9f, -+ 0x98, 0x9d, 0x94, 0x98, 0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94, -+ 0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b, 0x95, 0x90, 0x90, 0x9e, -+ 0x9c, 0x99, 0x97, 0x92, 0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97, -+ 0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d, 0x90, 0x9f, 0x96, 0x9c, -+ 0x9a, 0x99, 0x9d, 0x90, 0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b, -+ 0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83, -+ 0x8b, 0x87, 0x81, 0x84, 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b, -+ 0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81, -+ 0x84, 0x8e, 0x81, 0x87, 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d, -+ 0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85, -+ 0x85, 0x86, 0x88, 0x8b, 0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18, -+ 0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14, 0x1a, 0x1c, 0x19, 0x15, -+ 0x13, 0x16, 0x1e, 0x1b, 0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12, -+ 0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17, 0x19, 0x14, 0x1c, 0x1a, -+ 0x1e, 0x18, 0x12, 0x1d, 0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10, -+ 0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b, 0xdd, 0xd1, 0xd2, 0xdf, -+ 0xd8, 0xdd, 0xd4, 0xd8, 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4, -+ 0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde, -+ 0xdc, 0xd9, 0xd7, 0xd2, 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7, -+ 0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc, -+ 0xda, 0xd9, 0xdd, 0xd0, 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb, -+ 0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3, -+ 0xab, 0xa7, 0xa1, 0xa4, 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab, -+ 0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1, -+ 0xa4, 0xae, 0xa1, 0xa7, 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad, -+ 0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5, -+ 0xa5, 0xa6, 0xa8, 0xab, 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38, -+ 0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35, -+ 0x33, 0x36, 0x3e, 0x3b, 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32, -+ 0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a, -+ 0x3e, 0x38, 0x32, 0x3d, 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30, -+ 0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b, 0xed, 0xe1, 0xe2, 0xef, -+ 0xe8, 0xed, 0xe4, 0xe8, 0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4, -+ 0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb, 0xe5, 0xe0, 0xe0, 0xee, -+ 0xec, 0xe9, 0xe7, 0xe2, 0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7, -+ 0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed, 0xe0, 0xef, 0xe6, 0xec, -+ 0xea, 0xe9, 0xed, 0xe0, 0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb, -+ 0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8, 0xc6, 0xca, 0xcf, 0xc3, -+ 0xcb, 0xc7, 0xc1, 0xc4, 0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb, -+ 0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2, 0xc7, 0xc2, 0xcb, 0xc1, -+ 0xc4, 0xce, 0xc1, 0xc7, 0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd, -+ 0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0, 0xcf, 0xc3, 0xc3, 0xc5, -+ 0xc5, 0xc6, 0xc8, 0xcb, 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38, -+ 0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35, -+ 0x33, 0x36, 0x3e, 0x3b, 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32, -+ 0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a, -+ 0x3e, 0x38, 0x32, 0x3d, 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30, -+ 0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b, 0x9d, 0x91, 0x92, 0x9f, -+ 0x98, 0x9d, 0x94, 0x98, 0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94, -+ 0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b, 0x95, 0x90, 0x90, 0x9e, -+ 0x9c, 0x99, 0x97, 0x92, 0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97, -+ 0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d, 0x90, 0x9f, 0x96, 0x9c, -+ 0x9a, 0x99, 0x9d, 0x90, 0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b, -+ 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58, 0x56, 0x5a, 0x5f, 0x53, -+ 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b, -+ 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52, 0x57, 0x52, 0x5b, 0x51, -+ 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d, -+ 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50, 0x5f, 0x53, 0x53, 0x55, -+ 0x55, 0x56, 0x58, 0x5b, 0x7d, 0x71, 0x72, 0x7f, 0x78, 0x7d, 0x74, 0x78, -+ 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74, 0x7a, 0x7c, 0x79, 0x75, -+ 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e, 0x7c, 0x79, 0x77, 0x72, -+ 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77, 0x79, 0x74, 0x7c, 0x7a, -+ 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c, 0x7a, 0x79, 0x7d, 0x70, -+ 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b, 0xcd, 0xc1, 0xc2, 0xcf, -+ 0xc8, 0xcd, 0xc4, 0xc8, 0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4, -+ 0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb, 0xc5, 0xc0, 0xc0, 0xce, -+ 0xcc, 0xc9, 0xc7, 0xc2, 0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7, -+ 0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd, 0xc0, 0xcf, 0xc6, 0xcc, -+ 0xca, 0xc9, 0xcd, 0xc0, 0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb, -+ 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58, 0x56, 0x5a, 0x5f, 0x53, -+ 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b, -+ 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52, 0x57, 0x52, 0x5b, 0x51, -+ 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d, -+ 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50, 0x5f, 0x53, 0x53, 0x55, -+ 0x55, 0x56, 0x58, 0x5b, 0x2d, 0x21, 0x22, 0x2f, 0x28, 0x2d, 0x24, 0x28, -+ 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24, 0x2a, 0x2c, 0x29, 0x25, -+ 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e, 0x2c, 0x29, 0x27, 0x22, -+ 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27, 0x29, 0x24, 0x2c, 0x2a, -+ 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c, 0x2a, 0x29, 0x2d, 0x20, -+ 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b, 0xad, 0xa1, 0xa2, 0xaf, -+ 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3, 0xab, 0xa7, 0xa1, 0xa4, -+ 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab, 0xa5, 0xa0, 0xa0, 0xae, -+ 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1, 0xa4, 0xae, 0xa1, 0xa7, -+ 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad, 0xa0, 0xaf, 0xa6, 0xac, -+ 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5, 0xa5, 0xa6, 0xa8, 0xab, -+ 0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8, 0xf6, 0xfa, 0xff, 0xf3, -+ 0xfb, 0xf7, 0xf1, 0xf4, 0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb, -+ 0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2, 0xf7, 0xf2, 0xfb, 0xf1, -+ 0xf4, 0xfe, 0xf1, 0xf7, 0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd, -+ 0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0, 0xff, 0xf3, 0xf3, 0xf5, -+ 0xf5, 0xf6, 0xf8, 0xfb, 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68, -+ 0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65, -+ 0x63, 0x66, 0x6e, 0x6b, 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62, -+ 0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a, -+ 0x6e, 0x68, 0x62, 0x6d, 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60, -+ 0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b, 0x8d, 0x81, 0x82, 0x8f, -+ 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83, 0x8b, 0x87, 0x81, 0x84, -+ 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b, 0x85, 0x80, 0x80, 0x8e, -+ 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81, 0x84, 0x8e, 0x81, 0x87, -+ 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d, 0x80, 0x8f, 0x86, 0x8c, -+ 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85, 0x85, 0x86, 0x88, 0x8b, -+ 0x1d, 0x11, 0x12, 0x1f, 0x18, 0x1d, 0x14, 0x18, 0x16, 0x1a, 0x1f, 0x13, -+ 0x1b, 0x17, 0x11, 0x14, 0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b, -+ 0x15, 0x10, 0x10, 0x1e, 0x1c, 0x19, 0x17, 0x12, 0x17, 0x12, 0x1b, 0x11, -+ 0x14, 0x1e, 0x11, 0x17, 0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d, -+ 0x10, 0x1f, 0x16, 0x1c, 0x1a, 0x19, 0x1d, 0x10, 0x1f, 0x13, 0x13, 0x15, -+ 0x15, 0x16, 0x18, 0x1b, 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68, -+ 0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65, -+ 0x63, 0x66, 0x6e, 0x6b, 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62, -+ 0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a, -+ 0x6e, 0x68, 0x62, 0x6d, 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60, -+ 0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b, 0x1d, 0x11, 0x12, 0x1f, -+ 0x18, 0x1d, 0x14, 0x18, 0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14, -+ 0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b, 0x15, 0x10, 0x10, 0x1e, -+ 0x1c, 0x19, 0x17, 0x12, 0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17, -+ 0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d, 0x10, 0x1f, 0x16, 0x1c, -+ 0x1a, 0x19, 0x1d, 0x10, 0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b, -+ 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68, 0x66, 0x6a, 0x6f, 0x63, -+ 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65, 0x63, 0x66, 0x6e, 0x6b, -+ 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62, 0x67, 0x62, 0x6b, 0x61, -+ 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a, 0x6e, 0x68, 0x62, 0x6d, -+ 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60, 0x6f, 0x63, 0x63, 0x65, -+ 0x65, 0x66, 0x68, 0x6b, 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48, -+ 0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45, -+ 0x43, 0x46, 0x4e, 0x4b, 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42, -+ 0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a, -+ 0x4e, 0x48, 0x42, 0x4d, 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40, -+ 0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b, 0xbd, 0xb1, 0xb2, 0xbf, -+ 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3, 0xbb, 0xb7, 0xb1, 0xb4, -+ 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb, 0xb5, 0xb0, 0xb0, 0xbe, -+ 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1, 0xb4, 0xbe, 0xb1, 0xb7, -+ 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd, 0xb0, 0xbf, 0xb6, 0xbc, -+ 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb8, 0xbb, -+ 0xbd, 0xb1, 0xb2, 0xbf, 0xb8, 0xbd, 0xb4, 0xb8, 0xb6, 0xba, 0xbf, 0xb3, -+ 0xbb, 0xb7, 0xb1, 0xb4, 0xba, 0xbc, 0xb9, 0xb5, 0xb3, 0xb6, 0xbe, 0xbb, -+ 0xb5, 0xb0, 0xb0, 0xbe, 0xbc, 0xb9, 0xb7, 0xb2, 0xb7, 0xb2, 0xbb, 0xb1, -+ 0xb4, 0xbe, 0xb1, 0xb7, 0xb9, 0xb4, 0xbc, 0xba, 0xbe, 0xb8, 0xb2, 0xbd, -+ 0xb0, 0xbf, 0xb6, 0xbc, 0xba, 0xb9, 0xbd, 0xb0, 0xbf, 0xb3, 0xb3, 0xb5, -+ 0xb5, 0xb6, 0xb8, 0xbb, 0xdd, 0xd1, 0xd2, 0xdf, 0xd8, 0xdd, 0xd4, 0xd8, -+ 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4, 0xda, 0xdc, 0xd9, 0xd5, -+ 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde, 0xdc, 0xd9, 0xd7, 0xd2, -+ 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7, 0xd9, 0xd4, 0xdc, 0xda, -+ 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc, 0xda, 0xd9, 0xdd, 0xd0, -+ 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb, 0xdd, 0xd1, 0xd2, 0xdf, -+ 0xd8, 0xdd, 0xd4, 0xd8, 0xd6, 0xda, 0xdf, 0xd3, 0xdb, 0xd7, 0xd1, 0xd4, -+ 0xda, 0xdc, 0xd9, 0xd5, 0xd3, 0xd6, 0xde, 0xdb, 0xd5, 0xd0, 0xd0, 0xde, -+ 0xdc, 0xd9, 0xd7, 0xd2, 0xd7, 0xd2, 0xdb, 0xd1, 0xd4, 0xde, 0xd1, 0xd7, -+ 0xd9, 0xd4, 0xdc, 0xda, 0xde, 0xd8, 0xd2, 0xdd, 0xd0, 0xdf, 0xd6, 0xdc, -+ 0xda, 0xd9, 0xdd, 0xd0, 0xdf, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd8, 0xdb, -+ 0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83, -+ 0x8b, 0x87, 0x81, 0x84, 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b, -+ 0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81, -+ 0x84, 0x8e, 0x81, 0x87, 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d, -+ 0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85, -+ 0x85, 0x86, 0x88, 0x8b, 0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8, -+ 0xc6, 0xca, 0xcf, 0xc3, 0xcb, 0xc7, 0xc1, 0xc4, 0xca, 0xcc, 0xc9, 0xc5, -+ 0xc3, 0xc6, 0xce, 0xcb, 0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2, -+ 0xc7, 0xc2, 0xcb, 0xc1, 0xc4, 0xce, 0xc1, 0xc7, 0xc9, 0xc4, 0xcc, 0xca, -+ 0xce, 0xc8, 0xc2, 0xcd, 0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0, -+ 0xcf, 0xc3, 0xc3, 0xc5, 0xc5, 0xc6, 0xc8, 0xcb, 0x1d, 0x11, 0x12, 0x1f, -+ 0x18, 0x1d, 0x14, 0x18, 0x16, 0x1a, 0x1f, 0x13, 0x1b, 0x17, 0x11, 0x14, -+ 0x1a, 0x1c, 0x19, 0x15, 0x13, 0x16, 0x1e, 0x1b, 0x15, 0x10, 0x10, 0x1e, -+ 0x1c, 0x19, 0x17, 0x12, 0x17, 0x12, 0x1b, 0x11, 0x14, 0x1e, 0x11, 0x17, -+ 0x19, 0x14, 0x1c, 0x1a, 0x1e, 0x18, 0x12, 0x1d, 0x10, 0x1f, 0x16, 0x1c, -+ 0x1a, 0x19, 0x1d, 0x10, 0x1f, 0x13, 0x13, 0x15, 0x15, 0x16, 0x18, 0x1b, -+ 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38, 0x36, 0x3a, 0x3f, 0x33, -+ 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35, 0x33, 0x36, 0x3e, 0x3b, -+ 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32, 0x37, 0x32, 0x3b, 0x31, -+ 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a, 0x3e, 0x38, 0x32, 0x3d, -+ 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30, 0x3f, 0x33, 0x33, 0x35, -+ 0x35, 0x36, 0x38, 0x3b, 0x4d, 0x41, 0x42, 0x4f, 0x48, 0x4d, 0x44, 0x48, -+ 0x46, 0x4a, 0x4f, 0x43, 0x4b, 0x47, 0x41, 0x44, 0x4a, 0x4c, 0x49, 0x45, -+ 0x43, 0x46, 0x4e, 0x4b, 0x45, 0x40, 0x40, 0x4e, 0x4c, 0x49, 0x47, 0x42, -+ 0x47, 0x42, 0x4b, 0x41, 0x44, 0x4e, 0x41, 0x47, 0x49, 0x44, 0x4c, 0x4a, -+ 0x4e, 0x48, 0x42, 0x4d, 0x40, 0x4f, 0x46, 0x4c, 0x4a, 0x49, 0x4d, 0x40, -+ 0x4f, 0x43, 0x43, 0x45, 0x45, 0x46, 0x48, 0x4b, 0x7d, 0x71, 0x72, 0x7f, -+ 0x78, 0x7d, 0x74, 0x78, 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74, -+ 0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e, -+ 0x7c, 0x79, 0x77, 0x72, 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77, -+ 0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c, -+ 0x7a, 0x79, 0x7d, 0x70, 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b, -+ 0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3, -+ 0xab, 0xa7, 0xa1, 0xa4, 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab, -+ 0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1, -+ 0xa4, 0xae, 0xa1, 0xa7, 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad, -+ 0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5, -+ 0xa5, 0xa6, 0xa8, 0xab, 0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8, -+ 0xe6, 0xea, 0xef, 0xe3, 0xeb, 0xe7, 0xe1, 0xe4, 0xea, 0xec, 0xe9, 0xe5, -+ 0xe3, 0xe6, 0xee, 0xeb, 0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2, -+ 0xe7, 0xe2, 0xeb, 0xe1, 0xe4, 0xee, 0xe1, 0xe7, 0xe9, 0xe4, 0xec, 0xea, -+ 0xee, 0xe8, 0xe2, 0xed, 0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0, -+ 0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe8, 0xeb, 0x7d, 0x71, 0x72, 0x7f, -+ 0x78, 0x7d, 0x74, 0x78, 0x76, 0x7a, 0x7f, 0x73, 0x7b, 0x77, 0x71, 0x74, -+ 0x7a, 0x7c, 0x79, 0x75, 0x73, 0x76, 0x7e, 0x7b, 0x75, 0x70, 0x70, 0x7e, -+ 0x7c, 0x79, 0x77, 0x72, 0x77, 0x72, 0x7b, 0x71, 0x74, 0x7e, 0x71, 0x77, -+ 0x79, 0x74, 0x7c, 0x7a, 0x7e, 0x78, 0x72, 0x7d, 0x70, 0x7f, 0x76, 0x7c, -+ 0x7a, 0x79, 0x7d, 0x70, 0x7f, 0x73, 0x73, 0x75, 0x75, 0x76, 0x78, 0x7b, -+ 0xad, 0xa1, 0xa2, 0xaf, 0xa8, 0xad, 0xa4, 0xa8, 0xa6, 0xaa, 0xaf, 0xa3, -+ 0xab, 0xa7, 0xa1, 0xa4, 0xaa, 0xac, 0xa9, 0xa5, 0xa3, 0xa6, 0xae, 0xab, -+ 0xa5, 0xa0, 0xa0, 0xae, 0xac, 0xa9, 0xa7, 0xa2, 0xa7, 0xa2, 0xab, 0xa1, -+ 0xa4, 0xae, 0xa1, 0xa7, 0xa9, 0xa4, 0xac, 0xaa, 0xae, 0xa8, 0xa2, 0xad, -+ 0xa0, 0xaf, 0xa6, 0xac, 0xaa, 0xa9, 0xad, 0xa0, 0xaf, 0xa3, 0xa3, 0xa5, -+ 0xa5, 0xa6, 0xa8, 0xab, 0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98, -+ 0x96, 0x9a, 0x9f, 0x93, 0x9b, 0x97, 0x91, 0x94, 0x9a, 0x9c, 0x99, 0x95, -+ 0x93, 0x96, 0x9e, 0x9b, 0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92, -+ 0x97, 0x92, 0x9b, 0x91, 0x94, 0x9e, 0x91, 0x97, 0x99, 0x94, 0x9c, 0x9a, -+ 0x9e, 0x98, 0x92, 0x9d, 0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90, -+ 0x9f, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b, 0xfd, 0xf1, 0xf2, 0xff, -+ 0xf8, 0xfd, 0xf4, 0xf8, 0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4, -+ 0xfa, 0xfc, 0xf9, 0xf5, 0xf3, 0xf6, 0xfe, 0xfb, 0xf5, 0xf0, 0xf0, 0xfe, -+ 0xfc, 0xf9, 0xf7, 0xf2, 0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7, -+ 0xf9, 0xf4, 0xfc, 0xfa, 0xfe, 0xf8, 0xf2, 0xfd, 0xf0, 0xff, 0xf6, 0xfc, -+ 0xfa, 0xf9, 0xfd, 0xf0, 0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb, -+ 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58, 0x56, 0x5a, 0x5f, 0x53, -+ 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55, 0x53, 0x56, 0x5e, 0x5b, -+ 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52, 0x57, 0x52, 0x5b, 0x51, -+ 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a, 0x5e, 0x58, 0x52, 0x5d, -+ 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50, 0x5f, 0x53, 0x53, 0x55, -+ 0x55, 0x56, 0x58, 0x5b, 0x6d, 0x61, 0x62, 0x6f, 0x68, 0x6d, 0x64, 0x68, -+ 0x66, 0x6a, 0x6f, 0x63, 0x6b, 0x67, 0x61, 0x64, 0x6a, 0x6c, 0x69, 0x65, -+ 0x63, 0x66, 0x6e, 0x6b, 0x65, 0x60, 0x60, 0x6e, 0x6c, 0x69, 0x67, 0x62, -+ 0x67, 0x62, 0x6b, 0x61, 0x64, 0x6e, 0x61, 0x67, 0x69, 0x64, 0x6c, 0x6a, -+ 0x6e, 0x68, 0x62, 0x6d, 0x60, 0x6f, 0x66, 0x6c, 0x6a, 0x69, 0x6d, 0x60, -+ 0x6f, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6b, 0x0d, 0x01, 0x02, 0x0f, -+ 0x08, 0x0d, 0x04, 0x08, 0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04, -+ 0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b, 0x05, 0x00, 0x00, 0x0e, -+ 0x0c, 0x09, 0x07, 0x02, 0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07, -+ 0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d, 0x00, 0x0f, 0x06, 0x0c, -+ 0x0a, 0x09, 0x0d, 0x00, 0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b, -+ 0x8d, 0x81, 0x82, 0x8f, 0x88, 0x8d, 0x84, 0x88, 0x86, 0x8a, 0x8f, 0x83, -+ 0x8b, 0x87, 0x81, 0x84, 0x8a, 0x8c, 0x89, 0x85, 0x83, 0x86, 0x8e, 0x8b, -+ 0x85, 0x80, 0x80, 0x8e, 0x8c, 0x89, 0x87, 0x82, 0x87, 0x82, 0x8b, 0x81, -+ 0x84, 0x8e, 0x81, 0x87, 0x89, 0x84, 0x8c, 0x8a, 0x8e, 0x88, 0x82, 0x8d, -+ 0x80, 0x8f, 0x86, 0x8c, 0x8a, 0x89, 0x8d, 0x80, 0x8f, 0x83, 0x83, 0x85, -+ 0x85, 0x86, 0x88, 0x8b, 0xfd, 0xf1, 0xf2, 0xff, 0xf8, 0xfd, 0xf4, 0xf8, -+ 0xf6, 0xfa, 0xff, 0xf3, 0xfb, 0xf7, 0xf1, 0xf4, 0xfa, 0xfc, 0xf9, 0xf5, -+ 0xf3, 0xf6, 0xfe, 0xfb, 0xf5, 0xf0, 0xf0, 0xfe, 0xfc, 0xf9, 0xf7, 0xf2, -+ 0xf7, 0xf2, 0xfb, 0xf1, 0xf4, 0xfe, 0xf1, 0xf7, 0xf9, 0xf4, 0xfc, 0xfa, -+ 0xfe, 0xf8, 0xf2, 0xfd, 0xf0, 0xff, 0xf6, 0xfc, 0xfa, 0xf9, 0xfd, 0xf0, -+ 0xff, 0xf3, 0xf3, 0xf5, 0xf5, 0xf6, 0xf8, 0xfb, 0x0d, 0x01, 0x02, 0x0f, -+ 0x08, 0x0d, 0x04, 0x08, 0x06, 0x0a, 0x0f, 0x03, 0x0b, 0x07, 0x01, 0x04, -+ 0x0a, 0x0c, 0x09, 0x05, 0x03, 0x06, 0x0e, 0x0b, 0x05, 0x00, 0x00, 0x0e, -+ 0x0c, 0x09, 0x07, 0x02, 0x07, 0x02, 0x0b, 0x01, 0x04, 0x0e, 0x01, 0x07, -+ 0x09, 0x04, 0x0c, 0x0a, 0x0e, 0x08, 0x02, 0x0d, 0x00, 0x0f, 0x06, 0x0c, -+ 0x0a, 0x09, 0x0d, 0x00, 0x0f, 0x03, 0x03, 0x05, 0x05, 0x06, 0x08, 0x0b, -+ 0xed, 0xe1, 0xe2, 0xef, 0xe8, 0xed, 0xe4, 0xe8, 0xe6, 0xea, 0xef, 0xe3, -+ 0xeb, 0xe7, 0xe1, 0xe4, 0xea, 0xec, 0xe9, 0xe5, 0xe3, 0xe6, 0xee, 0xeb, -+ 0xe5, 0xe0, 0xe0, 0xee, 0xec, 0xe9, 0xe7, 0xe2, 0xe7, 0xe2, 0xeb, 0xe1, -+ 0xe4, 0xee, 0xe1, 0xe7, 0xe9, 0xe4, 0xec, 0xea, 0xee, 0xe8, 0xe2, 0xed, -+ 0xe0, 0xef, 0xe6, 0xec, 0xea, 0xe9, 0xed, 0xe0, 0xef, 0xe3, 0xe3, 0xe5, -+ 0xe5, 0xe6, 0xe8, 0xeb, 0x5d, 0x51, 0x52, 0x5f, 0x58, 0x5d, 0x54, 0x58, -+ 0x56, 0x5a, 0x5f, 0x53, 0x5b, 0x57, 0x51, 0x54, 0x5a, 0x5c, 0x59, 0x55, -+ 0x53, 0x56, 0x5e, 0x5b, 0x55, 0x50, 0x50, 0x5e, 0x5c, 0x59, 0x57, 0x52, -+ 0x57, 0x52, 0x5b, 0x51, 0x54, 0x5e, 0x51, 0x57, 0x59, 0x54, 0x5c, 0x5a, -+ 0x5e, 0x58, 0x52, 0x5d, 0x50, 0x5f, 0x56, 0x5c, 0x5a, 0x59, 0x5d, 0x50, -+ 0x5f, 0x53, 0x53, 0x55, 0x55, 0x56, 0x58, 0x5b, 0x2d, 0x21, 0x22, 0x2f, -+ 0x28, 0x2d, 0x24, 0x28, 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24, -+ 0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e, -+ 0x2c, 0x29, 0x27, 0x22, 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27, -+ 0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c, -+ 0x2a, 0x29, 0x2d, 0x20, 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b, -+ 0x9d, 0x91, 0x92, 0x9f, 0x98, 0x9d, 0x94, 0x98, 0x96, 0x9a, 0x9f, 0x93, -+ 0x9b, 0x97, 0x91, 0x94, 0x9a, 0x9c, 0x99, 0x95, 0x93, 0x96, 0x9e, 0x9b, -+ 0x95, 0x90, 0x90, 0x9e, 0x9c, 0x99, 0x97, 0x92, 0x97, 0x92, 0x9b, 0x91, -+ 0x94, 0x9e, 0x91, 0x97, 0x99, 0x94, 0x9c, 0x9a, 0x9e, 0x98, 0x92, 0x9d, -+ 0x90, 0x9f, 0x96, 0x9c, 0x9a, 0x99, 0x9d, 0x90, 0x9f, 0x93, 0x93, 0x95, -+ 0x95, 0x96, 0x98, 0x9b, 0x3d, 0x31, 0x32, 0x3f, 0x38, 0x3d, 0x34, 0x38, -+ 0x36, 0x3a, 0x3f, 0x33, 0x3b, 0x37, 0x31, 0x34, 0x3a, 0x3c, 0x39, 0x35, -+ 0x33, 0x36, 0x3e, 0x3b, 0x35, 0x30, 0x30, 0x3e, 0x3c, 0x39, 0x37, 0x32, -+ 0x37, 0x32, 0x3b, 0x31, 0x34, 0x3e, 0x31, 0x37, 0x39, 0x34, 0x3c, 0x3a, -+ 0x3e, 0x38, 0x32, 0x3d, 0x30, 0x3f, 0x36, 0x3c, 0x3a, 0x39, 0x3d, 0x30, -+ 0x3f, 0x33, 0x33, 0x35, 0x35, 0x36, 0x38, 0x3b, 0x2d, 0x21, 0x22, 0x2f, -+ 0x28, 0x2d, 0x24, 0x28, 0x26, 0x2a, 0x2f, 0x23, 0x2b, 0x27, 0x21, 0x24, -+ 0x2a, 0x2c, 0x29, 0x25, 0x23, 0x26, 0x2e, 0x2b, 0x25, 0x20, 0x20, 0x2e, -+ 0x2c, 0x29, 0x27, 0x22, 0x27, 0x22, 0x2b, 0x21, 0x24, 0x2e, 0x21, 0x27, -+ 0x29, 0x24, 0x2c, 0x2a, 0x2e, 0x28, 0x22, 0x2d, 0x20, 0x2f, 0x26, 0x2c, -+ 0x2a, 0x29, 0x2d, 0x20, 0x2f, 0x23, 0x23, 0x25, 0x25, 0x26, 0x28, 0x2b, -+ 0xcd, 0xc1, 0xc2, 0xcf, 0xc8, 0xcd, 0xc4, 0xc8, 0xc6, 0xca, 0xcf, 0xc3, -+ 0xcb, 0xc7, 0xc1, 0xc4, 0xca, 0xcc, 0xc9, 0xc5, 0xc3, 0xc6, 0xce, 0xcb, -+ 0xc5, 0xc0, 0xc0, 0xce, 0xcc, 0xc9, 0xc7, 0xc2, 0xc7, 0xc2, 0xcb, 0xc1, -+ 0xc4, 0xce, 0xc1, 0xc7, 0xc9, 0xc4, 0xcc, 0xca, 0xce, 0xc8, 0xc2, 0xcd, -+ 0xc0, 0xcf, 0xc6, 0xcc, 0xca, 0xc9, 0xcd, 0xc0, 0xcf, 0xc3, 0xc3, 0xc5, -+ 0xc5, 0xc6, 0xc8, 0xcb, -+ }, -+}; -+ -+const uint32_t ip_maskl[8][256] = { -+ { -+ 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000100, 0x00000101, -+ 0x00000100, 0x00000101, 0x00000000, 0x00000001, 0x00000000, 0x00000001, -+ 0x00000100, 0x00000101, 0x00000100, 0x00000101, 0x00010000, 0x00010001, -+ 0x00010000, 0x00010001, 0x00010100, 0x00010101, 0x00010100, 0x00010101, -+ 0x00010000, 0x00010001, 0x00010000, 0x00010001, 0x00010100, 0x00010101, -+ 0x00010100, 0x00010101, 0x00000000, 0x00000001, 0x00000000, 0x00000001, -+ 0x00000100, 0x00000101, 0x00000100, 0x00000101, 0x00000000, 0x00000001, -+ 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00000100, 0x00000101, -+ 0x00010000, 0x00010001, 0x00010000, 0x00010001, 0x00010100, 0x00010101, -+ 0x00010100, 0x00010101, 0x00010000, 0x00010001, 0x00010000, 0x00010001, -+ 0x00010100, 0x00010101, 0x00010100, 0x00010101, 0x01000000, 0x01000001, -+ 0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01000100, 0x01000101, -+ 0x01000000, 0x01000001, 0x01000000, 0x01000001, 0x01000100, 0x01000101, -+ 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010000, 0x01010001, -+ 0x01010100, 0x01010101, 0x01010100, 0x01010101, 0x01010000, 0x01010001, -+ 0x01010000, 0x01010001, 0x01010100, 0x01010101, 0x01010100, 0x01010101, -+ 0x01000000, 0x01000001, 0x01000000, 0x01000001, 0x01000100, 0x01000101, -+ 0x01000100, 0x01000101, 0x01000000, 0x01000001, 0x01000000, 0x01000001, -+ 0x01000100, 0x01000101, 0x01000100, 0x01000101, 0x01010000, 0x01010001, -+ 0x01010000, 0x01010001, 0x01010100, 0x01010101, 0x01010100, 0x01010101, -+ 0x01010000, 0x01010001, 0x01010000, 0x01010001, 0x01010100, 0x01010101, -+ 0x01010100, 0x01010101, 0x00000000, 0x00000001, 0x00000000, 0x00000001, -+ 0x00000100, 0x00000101, 0x00000100, 0x00000101, 0x00000000, 0x00000001, -+ 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00000100, 0x00000101, -+ 0x00010000, 0x00010001, 0x00010000, 0x00010001, 0x00010100, 0x00010101, -+ 0x00010100, 0x00010101, 0x00010000, 0x00010001, 0x00010000, 0x00010001, -+ 0x00010100, 0x00010101, 0x00010100, 0x00010101, 0x00000000, 0x00000001, -+ 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00000100, 0x00000101, -+ 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000100, 0x00000101, -+ 0x00000100, 0x00000101, 0x00010000, 0x00010001, 0x00010000, 0x00010001, -+ 0x00010100, 0x00010101, 0x00010100, 0x00010101, 0x00010000, 0x00010001, -+ 0x00010000, 0x00010001, 0x00010100, 0x00010101, 0x00010100, 0x00010101, -+ 0x01000000, 0x01000001, 0x01000000, 0x01000001, 0x01000100, 0x01000101, -+ 0x01000100, 0x01000101, 0x01000000, 0x01000001, 0x01000000, 0x01000001, -+ 0x01000100, 0x01000101, 0x01000100, 0x01000101, 0x01010000, 0x01010001, -+ 0x01010000, 0x01010001, 0x01010100, 0x01010101, 0x01010100, 0x01010101, -+ 0x01010000, 0x01010001, 0x01010000, 0x01010001, 0x01010100, 0x01010101, -+ 0x01010100, 0x01010101, 0x01000000, 0x01000001, 0x01000000, 0x01000001, -+ 0x01000100, 0x01000101, 0x01000100, 0x01000101, 0x01000000, 0x01000001, -+ 0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01000100, 0x01000101, -+ 0x01010000, 0x01010001, 0x01010000, 0x01010001, 0x01010100, 0x01010101, -+ 0x01010100, 0x01010101, 0x01010000, 0x01010001, 0x01010000, 0x01010001, -+ 0x01010100, 0x01010101, 0x01010100, 0x01010101, -+ }, -+ { -+ 0x00000000, 0x00000002, 0x00000000, 0x00000002, 0x00000200, 0x00000202, -+ 0x00000200, 0x00000202, 0x00000000, 0x00000002, 0x00000000, 0x00000002, -+ 0x00000200, 0x00000202, 0x00000200, 0x00000202, 0x00020000, 0x00020002, -+ 0x00020000, 0x00020002, 0x00020200, 0x00020202, 0x00020200, 0x00020202, -+ 0x00020000, 0x00020002, 0x00020000, 0x00020002, 0x00020200, 0x00020202, -+ 0x00020200, 0x00020202, 0x00000000, 0x00000002, 0x00000000, 0x00000002, -+ 0x00000200, 0x00000202, 0x00000200, 0x00000202, 0x00000000, 0x00000002, -+ 0x00000000, 0x00000002, 0x00000200, 0x00000202, 0x00000200, 0x00000202, -+ 0x00020000, 0x00020002, 0x00020000, 0x00020002, 0x00020200, 0x00020202, -+ 0x00020200, 0x00020202, 0x00020000, 0x00020002, 0x00020000, 0x00020002, -+ 0x00020200, 0x00020202, 0x00020200, 0x00020202, 0x02000000, 0x02000002, -+ 0x02000000, 0x02000002, 0x02000200, 0x02000202, 0x02000200, 0x02000202, -+ 0x02000000, 0x02000002, 0x02000000, 0x02000002, 0x02000200, 0x02000202, -+ 0x02000200, 0x02000202, 0x02020000, 0x02020002, 0x02020000, 0x02020002, -+ 0x02020200, 0x02020202, 0x02020200, 0x02020202, 0x02020000, 0x02020002, -+ 0x02020000, 0x02020002, 0x02020200, 0x02020202, 0x02020200, 0x02020202, -+ 0x02000000, 0x02000002, 0x02000000, 0x02000002, 0x02000200, 0x02000202, -+ 0x02000200, 0x02000202, 0x02000000, 0x02000002, 0x02000000, 0x02000002, -+ 0x02000200, 0x02000202, 0x02000200, 0x02000202, 0x02020000, 0x02020002, -+ 0x02020000, 0x02020002, 0x02020200, 0x02020202, 0x02020200, 0x02020202, -+ 0x02020000, 0x02020002, 0x02020000, 0x02020002, 0x02020200, 0x02020202, -+ 0x02020200, 0x02020202, 0x00000000, 0x00000002, 0x00000000, 0x00000002, -+ 0x00000200, 0x00000202, 0x00000200, 0x00000202, 0x00000000, 0x00000002, -+ 0x00000000, 0x00000002, 0x00000200, 0x00000202, 0x00000200, 0x00000202, -+ 0x00020000, 0x00020002, 0x00020000, 0x00020002, 0x00020200, 0x00020202, -+ 0x00020200, 0x00020202, 0x00020000, 0x00020002, 0x00020000, 0x00020002, -+ 0x00020200, 0x00020202, 0x00020200, 0x00020202, 0x00000000, 0x00000002, -+ 0x00000000, 0x00000002, 0x00000200, 0x00000202, 0x00000200, 0x00000202, -+ 0x00000000, 0x00000002, 0x00000000, 0x00000002, 0x00000200, 0x00000202, -+ 0x00000200, 0x00000202, 0x00020000, 0x00020002, 0x00020000, 0x00020002, -+ 0x00020200, 0x00020202, 0x00020200, 0x00020202, 0x00020000, 0x00020002, -+ 0x00020000, 0x00020002, 0x00020200, 0x00020202, 0x00020200, 0x00020202, -+ 0x02000000, 0x02000002, 0x02000000, 0x02000002, 0x02000200, 0x02000202, -+ 0x02000200, 0x02000202, 0x02000000, 0x02000002, 0x02000000, 0x02000002, -+ 0x02000200, 0x02000202, 0x02000200, 0x02000202, 0x02020000, 0x02020002, -+ 0x02020000, 0x02020002, 0x02020200, 0x02020202, 0x02020200, 0x02020202, -+ 0x02020000, 0x02020002, 0x02020000, 0x02020002, 0x02020200, 0x02020202, -+ 0x02020200, 0x02020202, 0x02000000, 0x02000002, 0x02000000, 0x02000002, -+ 0x02000200, 0x02000202, 0x02000200, 0x02000202, 0x02000000, 0x02000002, -+ 0x02000000, 0x02000002, 0x02000200, 0x02000202, 0x02000200, 0x02000202, -+ 0x02020000, 0x02020002, 0x02020000, 0x02020002, 0x02020200, 0x02020202, -+ 0x02020200, 0x02020202, 0x02020000, 0x02020002, 0x02020000, 0x02020002, -+ 0x02020200, 0x02020202, 0x02020200, 0x02020202, -+ }, -+ { -+ 0x00000000, 0x00000004, 0x00000000, 0x00000004, 0x00000400, 0x00000404, -+ 0x00000400, 0x00000404, 0x00000000, 0x00000004, 0x00000000, 0x00000004, -+ 0x00000400, 0x00000404, 0x00000400, 0x00000404, 0x00040000, 0x00040004, -+ 0x00040000, 0x00040004, 0x00040400, 0x00040404, 0x00040400, 0x00040404, -+ 0x00040000, 0x00040004, 0x00040000, 0x00040004, 0x00040400, 0x00040404, -+ 0x00040400, 0x00040404, 0x00000000, 0x00000004, 0x00000000, 0x00000004, -+ 0x00000400, 0x00000404, 0x00000400, 0x00000404, 0x00000000, 0x00000004, -+ 0x00000000, 0x00000004, 0x00000400, 0x00000404, 0x00000400, 0x00000404, -+ 0x00040000, 0x00040004, 0x00040000, 0x00040004, 0x00040400, 0x00040404, -+ 0x00040400, 0x00040404, 0x00040000, 0x00040004, 0x00040000, 0x00040004, -+ 0x00040400, 0x00040404, 0x00040400, 0x00040404, 0x04000000, 0x04000004, -+ 0x04000000, 0x04000004, 0x04000400, 0x04000404, 0x04000400, 0x04000404, -+ 0x04000000, 0x04000004, 0x04000000, 0x04000004, 0x04000400, 0x04000404, -+ 0x04000400, 0x04000404, 0x04040000, 0x04040004, 0x04040000, 0x04040004, -+ 0x04040400, 0x04040404, 0x04040400, 0x04040404, 0x04040000, 0x04040004, -+ 0x04040000, 0x04040004, 0x04040400, 0x04040404, 0x04040400, 0x04040404, -+ 0x04000000, 0x04000004, 0x04000000, 0x04000004, 0x04000400, 0x04000404, -+ 0x04000400, 0x04000404, 0x04000000, 0x04000004, 0x04000000, 0x04000004, -+ 0x04000400, 0x04000404, 0x04000400, 0x04000404, 0x04040000, 0x04040004, -+ 0x04040000, 0x04040004, 0x04040400, 0x04040404, 0x04040400, 0x04040404, -+ 0x04040000, 0x04040004, 0x04040000, 0x04040004, 0x04040400, 0x04040404, -+ 0x04040400, 0x04040404, 0x00000000, 0x00000004, 0x00000000, 0x00000004, -+ 0x00000400, 0x00000404, 0x00000400, 0x00000404, 0x00000000, 0x00000004, -+ 0x00000000, 0x00000004, 0x00000400, 0x00000404, 0x00000400, 0x00000404, -+ 0x00040000, 0x00040004, 0x00040000, 0x00040004, 0x00040400, 0x00040404, -+ 0x00040400, 0x00040404, 0x00040000, 0x00040004, 0x00040000, 0x00040004, -+ 0x00040400, 0x00040404, 0x00040400, 0x00040404, 0x00000000, 0x00000004, -+ 0x00000000, 0x00000004, 0x00000400, 0x00000404, 0x00000400, 0x00000404, -+ 0x00000000, 0x00000004, 0x00000000, 0x00000004, 0x00000400, 0x00000404, -+ 0x00000400, 0x00000404, 0x00040000, 0x00040004, 0x00040000, 0x00040004, -+ 0x00040400, 0x00040404, 0x00040400, 0x00040404, 0x00040000, 0x00040004, -+ 0x00040000, 0x00040004, 0x00040400, 0x00040404, 0x00040400, 0x00040404, -+ 0x04000000, 0x04000004, 0x04000000, 0x04000004, 0x04000400, 0x04000404, -+ 0x04000400, 0x04000404, 0x04000000, 0x04000004, 0x04000000, 0x04000004, -+ 0x04000400, 0x04000404, 0x04000400, 0x04000404, 0x04040000, 0x04040004, -+ 0x04040000, 0x04040004, 0x04040400, 0x04040404, 0x04040400, 0x04040404, -+ 0x04040000, 0x04040004, 0x04040000, 0x04040004, 0x04040400, 0x04040404, -+ 0x04040400, 0x04040404, 0x04000000, 0x04000004, 0x04000000, 0x04000004, -+ 0x04000400, 0x04000404, 0x04000400, 0x04000404, 0x04000000, 0x04000004, -+ 0x04000000, 0x04000004, 0x04000400, 0x04000404, 0x04000400, 0x04000404, -+ 0x04040000, 0x04040004, 0x04040000, 0x04040004, 0x04040400, 0x04040404, -+ 0x04040400, 0x04040404, 0x04040000, 0x04040004, 0x04040000, 0x04040004, -+ 0x04040400, 0x04040404, 0x04040400, 0x04040404, -+ }, -+ { -+ 0x00000000, 0x00000008, 0x00000000, 0x00000008, 0x00000800, 0x00000808, -+ 0x00000800, 0x00000808, 0x00000000, 0x00000008, 0x00000000, 0x00000008, -+ 0x00000800, 0x00000808, 0x00000800, 0x00000808, 0x00080000, 0x00080008, -+ 0x00080000, 0x00080008, 0x00080800, 0x00080808, 0x00080800, 0x00080808, -+ 0x00080000, 0x00080008, 0x00080000, 0x00080008, 0x00080800, 0x00080808, -+ 0x00080800, 0x00080808, 0x00000000, 0x00000008, 0x00000000, 0x00000008, -+ 0x00000800, 0x00000808, 0x00000800, 0x00000808, 0x00000000, 0x00000008, -+ 0x00000000, 0x00000008, 0x00000800, 0x00000808, 0x00000800, 0x00000808, -+ 0x00080000, 0x00080008, 0x00080000, 0x00080008, 0x00080800, 0x00080808, -+ 0x00080800, 0x00080808, 0x00080000, 0x00080008, 0x00080000, 0x00080008, -+ 0x00080800, 0x00080808, 0x00080800, 0x00080808, 0x08000000, 0x08000008, -+ 0x08000000, 0x08000008, 0x08000800, 0x08000808, 0x08000800, 0x08000808, -+ 0x08000000, 0x08000008, 0x08000000, 0x08000008, 0x08000800, 0x08000808, -+ 0x08000800, 0x08000808, 0x08080000, 0x08080008, 0x08080000, 0x08080008, -+ 0x08080800, 0x08080808, 0x08080800, 0x08080808, 0x08080000, 0x08080008, -+ 0x08080000, 0x08080008, 0x08080800, 0x08080808, 0x08080800, 0x08080808, -+ 0x08000000, 0x08000008, 0x08000000, 0x08000008, 0x08000800, 0x08000808, -+ 0x08000800, 0x08000808, 0x08000000, 0x08000008, 0x08000000, 0x08000008, -+ 0x08000800, 0x08000808, 0x08000800, 0x08000808, 0x08080000, 0x08080008, -+ 0x08080000, 0x08080008, 0x08080800, 0x08080808, 0x08080800, 0x08080808, -+ 0x08080000, 0x08080008, 0x08080000, 0x08080008, 0x08080800, 0x08080808, -+ 0x08080800, 0x08080808, 0x00000000, 0x00000008, 0x00000000, 0x00000008, -+ 0x00000800, 0x00000808, 0x00000800, 0x00000808, 0x00000000, 0x00000008, -+ 0x00000000, 0x00000008, 0x00000800, 0x00000808, 0x00000800, 0x00000808, -+ 0x00080000, 0x00080008, 0x00080000, 0x00080008, 0x00080800, 0x00080808, -+ 0x00080800, 0x00080808, 0x00080000, 0x00080008, 0x00080000, 0x00080008, -+ 0x00080800, 0x00080808, 0x00080800, 0x00080808, 0x00000000, 0x00000008, -+ 0x00000000, 0x00000008, 0x00000800, 0x00000808, 0x00000800, 0x00000808, -+ 0x00000000, 0x00000008, 0x00000000, 0x00000008, 0x00000800, 0x00000808, -+ 0x00000800, 0x00000808, 0x00080000, 0x00080008, 0x00080000, 0x00080008, -+ 0x00080800, 0x00080808, 0x00080800, 0x00080808, 0x00080000, 0x00080008, -+ 0x00080000, 0x00080008, 0x00080800, 0x00080808, 0x00080800, 0x00080808, -+ 0x08000000, 0x08000008, 0x08000000, 0x08000008, 0x08000800, 0x08000808, -+ 0x08000800, 0x08000808, 0x08000000, 0x08000008, 0x08000000, 0x08000008, -+ 0x08000800, 0x08000808, 0x08000800, 0x08000808, 0x08080000, 0x08080008, -+ 0x08080000, 0x08080008, 0x08080800, 0x08080808, 0x08080800, 0x08080808, -+ 0x08080000, 0x08080008, 0x08080000, 0x08080008, 0x08080800, 0x08080808, -+ 0x08080800, 0x08080808, 0x08000000, 0x08000008, 0x08000000, 0x08000008, -+ 0x08000800, 0x08000808, 0x08000800, 0x08000808, 0x08000000, 0x08000008, -+ 0x08000000, 0x08000008, 0x08000800, 0x08000808, 0x08000800, 0x08000808, -+ 0x08080000, 0x08080008, 0x08080000, 0x08080008, 0x08080800, 0x08080808, -+ 0x08080800, 0x08080808, 0x08080000, 0x08080008, 0x08080000, 0x08080008, -+ 0x08080800, 0x08080808, 0x08080800, 0x08080808, -+ }, -+ { -+ 0x00000000, 0x00000010, 0x00000000, 0x00000010, 0x00001000, 0x00001010, -+ 0x00001000, 0x00001010, 0x00000000, 0x00000010, 0x00000000, 0x00000010, -+ 0x00001000, 0x00001010, 0x00001000, 0x00001010, 0x00100000, 0x00100010, -+ 0x00100000, 0x00100010, 0x00101000, 0x00101010, 0x00101000, 0x00101010, -+ 0x00100000, 0x00100010, 0x00100000, 0x00100010, 0x00101000, 0x00101010, -+ 0x00101000, 0x00101010, 0x00000000, 0x00000010, 0x00000000, 0x00000010, -+ 0x00001000, 0x00001010, 0x00001000, 0x00001010, 0x00000000, 0x00000010, -+ 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00001000, 0x00001010, -+ 0x00100000, 0x00100010, 0x00100000, 0x00100010, 0x00101000, 0x00101010, -+ 0x00101000, 0x00101010, 0x00100000, 0x00100010, 0x00100000, 0x00100010, -+ 0x00101000, 0x00101010, 0x00101000, 0x00101010, 0x10000000, 0x10000010, -+ 0x10000000, 0x10000010, 0x10001000, 0x10001010, 0x10001000, 0x10001010, -+ 0x10000000, 0x10000010, 0x10000000, 0x10000010, 0x10001000, 0x10001010, -+ 0x10001000, 0x10001010, 0x10100000, 0x10100010, 0x10100000, 0x10100010, -+ 0x10101000, 0x10101010, 0x10101000, 0x10101010, 0x10100000, 0x10100010, -+ 0x10100000, 0x10100010, 0x10101000, 0x10101010, 0x10101000, 0x10101010, -+ 0x10000000, 0x10000010, 0x10000000, 0x10000010, 0x10001000, 0x10001010, -+ 0x10001000, 0x10001010, 0x10000000, 0x10000010, 0x10000000, 0x10000010, -+ 0x10001000, 0x10001010, 0x10001000, 0x10001010, 0x10100000, 0x10100010, -+ 0x10100000, 0x10100010, 0x10101000, 0x10101010, 0x10101000, 0x10101010, -+ 0x10100000, 0x10100010, 0x10100000, 0x10100010, 0x10101000, 0x10101010, -+ 0x10101000, 0x10101010, 0x00000000, 0x00000010, 0x00000000, 0x00000010, -+ 0x00001000, 0x00001010, 0x00001000, 0x00001010, 0x00000000, 0x00000010, -+ 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00001000, 0x00001010, -+ 0x00100000, 0x00100010, 0x00100000, 0x00100010, 0x00101000, 0x00101010, -+ 0x00101000, 0x00101010, 0x00100000, 0x00100010, 0x00100000, 0x00100010, -+ 0x00101000, 0x00101010, 0x00101000, 0x00101010, 0x00000000, 0x00000010, -+ 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00001000, 0x00001010, -+ 0x00000000, 0x00000010, 0x00000000, 0x00000010, 0x00001000, 0x00001010, -+ 0x00001000, 0x00001010, 0x00100000, 0x00100010, 0x00100000, 0x00100010, -+ 0x00101000, 0x00101010, 0x00101000, 0x00101010, 0x00100000, 0x00100010, -+ 0x00100000, 0x00100010, 0x00101000, 0x00101010, 0x00101000, 0x00101010, -+ 0x10000000, 0x10000010, 0x10000000, 0x10000010, 0x10001000, 0x10001010, -+ 0x10001000, 0x10001010, 0x10000000, 0x10000010, 0x10000000, 0x10000010, -+ 0x10001000, 0x10001010, 0x10001000, 0x10001010, 0x10100000, 0x10100010, -+ 0x10100000, 0x10100010, 0x10101000, 0x10101010, 0x10101000, 0x10101010, -+ 0x10100000, 0x10100010, 0x10100000, 0x10100010, 0x10101000, 0x10101010, -+ 0x10101000, 0x10101010, 0x10000000, 0x10000010, 0x10000000, 0x10000010, -+ 0x10001000, 0x10001010, 0x10001000, 0x10001010, 0x10000000, 0x10000010, -+ 0x10000000, 0x10000010, 0x10001000, 0x10001010, 0x10001000, 0x10001010, -+ 0x10100000, 0x10100010, 0x10100000, 0x10100010, 0x10101000, 0x10101010, -+ 0x10101000, 0x10101010, 0x10100000, 0x10100010, 0x10100000, 0x10100010, -+ 0x10101000, 0x10101010, 0x10101000, 0x10101010, -+ }, -+ { -+ 0x00000000, 0x00000020, 0x00000000, 0x00000020, 0x00002000, 0x00002020, -+ 0x00002000, 0x00002020, 0x00000000, 0x00000020, 0x00000000, 0x00000020, -+ 0x00002000, 0x00002020, 0x00002000, 0x00002020, 0x00200000, 0x00200020, -+ 0x00200000, 0x00200020, 0x00202000, 0x00202020, 0x00202000, 0x00202020, -+ 0x00200000, 0x00200020, 0x00200000, 0x00200020, 0x00202000, 0x00202020, -+ 0x00202000, 0x00202020, 0x00000000, 0x00000020, 0x00000000, 0x00000020, -+ 0x00002000, 0x00002020, 0x00002000, 0x00002020, 0x00000000, 0x00000020, -+ 0x00000000, 0x00000020, 0x00002000, 0x00002020, 0x00002000, 0x00002020, -+ 0x00200000, 0x00200020, 0x00200000, 0x00200020, 0x00202000, 0x00202020, -+ 0x00202000, 0x00202020, 0x00200000, 0x00200020, 0x00200000, 0x00200020, -+ 0x00202000, 0x00202020, 0x00202000, 0x00202020, 0x20000000, 0x20000020, -+ 0x20000000, 0x20000020, 0x20002000, 0x20002020, 0x20002000, 0x20002020, -+ 0x20000000, 0x20000020, 0x20000000, 0x20000020, 0x20002000, 0x20002020, -+ 0x20002000, 0x20002020, 0x20200000, 0x20200020, 0x20200000, 0x20200020, -+ 0x20202000, 0x20202020, 0x20202000, 0x20202020, 0x20200000, 0x20200020, -+ 0x20200000, 0x20200020, 0x20202000, 0x20202020, 0x20202000, 0x20202020, -+ 0x20000000, 0x20000020, 0x20000000, 0x20000020, 0x20002000, 0x20002020, -+ 0x20002000, 0x20002020, 0x20000000, 0x20000020, 0x20000000, 0x20000020, -+ 0x20002000, 0x20002020, 0x20002000, 0x20002020, 0x20200000, 0x20200020, -+ 0x20200000, 0x20200020, 0x20202000, 0x20202020, 0x20202000, 0x20202020, -+ 0x20200000, 0x20200020, 0x20200000, 0x20200020, 0x20202000, 0x20202020, -+ 0x20202000, 0x20202020, 0x00000000, 0x00000020, 0x00000000, 0x00000020, -+ 0x00002000, 0x00002020, 0x00002000, 0x00002020, 0x00000000, 0x00000020, -+ 0x00000000, 0x00000020, 0x00002000, 0x00002020, 0x00002000, 0x00002020, -+ 0x00200000, 0x00200020, 0x00200000, 0x00200020, 0x00202000, 0x00202020, -+ 0x00202000, 0x00202020, 0x00200000, 0x00200020, 0x00200000, 0x00200020, -+ 0x00202000, 0x00202020, 0x00202000, 0x00202020, 0x00000000, 0x00000020, -+ 0x00000000, 0x00000020, 0x00002000, 0x00002020, 0x00002000, 0x00002020, -+ 0x00000000, 0x00000020, 0x00000000, 0x00000020, 0x00002000, 0x00002020, -+ 0x00002000, 0x00002020, 0x00200000, 0x00200020, 0x00200000, 0x00200020, -+ 0x00202000, 0x00202020, 0x00202000, 0x00202020, 0x00200000, 0x00200020, -+ 0x00200000, 0x00200020, 0x00202000, 0x00202020, 0x00202000, 0x00202020, -+ 0x20000000, 0x20000020, 0x20000000, 0x20000020, 0x20002000, 0x20002020, -+ 0x20002000, 0x20002020, 0x20000000, 0x20000020, 0x20000000, 0x20000020, -+ 0x20002000, 0x20002020, 0x20002000, 0x20002020, 0x20200000, 0x20200020, -+ 0x20200000, 0x20200020, 0x20202000, 0x20202020, 0x20202000, 0x20202020, -+ 0x20200000, 0x20200020, 0x20200000, 0x20200020, 0x20202000, 0x20202020, -+ 0x20202000, 0x20202020, 0x20000000, 0x20000020, 0x20000000, 0x20000020, -+ 0x20002000, 0x20002020, 0x20002000, 0x20002020, 0x20000000, 0x20000020, -+ 0x20000000, 0x20000020, 0x20002000, 0x20002020, 0x20002000, 0x20002020, -+ 0x20200000, 0x20200020, 0x20200000, 0x20200020, 0x20202000, 0x20202020, -+ 0x20202000, 0x20202020, 0x20200000, 0x20200020, 0x20200000, 0x20200020, -+ 0x20202000, 0x20202020, 0x20202000, 0x20202020, -+ }, -+ { -+ 0x00000000, 0x00000040, 0x00000000, 0x00000040, 0x00004000, 0x00004040, -+ 0x00004000, 0x00004040, 0x00000000, 0x00000040, 0x00000000, 0x00000040, -+ 0x00004000, 0x00004040, 0x00004000, 0x00004040, 0x00400000, 0x00400040, -+ 0x00400000, 0x00400040, 0x00404000, 0x00404040, 0x00404000, 0x00404040, -+ 0x00400000, 0x00400040, 0x00400000, 0x00400040, 0x00404000, 0x00404040, -+ 0x00404000, 0x00404040, 0x00000000, 0x00000040, 0x00000000, 0x00000040, -+ 0x00004000, 0x00004040, 0x00004000, 0x00004040, 0x00000000, 0x00000040, -+ 0x00000000, 0x00000040, 0x00004000, 0x00004040, 0x00004000, 0x00004040, -+ 0x00400000, 0x00400040, 0x00400000, 0x00400040, 0x00404000, 0x00404040, -+ 0x00404000, 0x00404040, 0x00400000, 0x00400040, 0x00400000, 0x00400040, -+ 0x00404000, 0x00404040, 0x00404000, 0x00404040, 0x40000000, 0x40000040, -+ 0x40000000, 0x40000040, 0x40004000, 0x40004040, 0x40004000, 0x40004040, -+ 0x40000000, 0x40000040, 0x40000000, 0x40000040, 0x40004000, 0x40004040, -+ 0x40004000, 0x40004040, 0x40400000, 0x40400040, 0x40400000, 0x40400040, -+ 0x40404000, 0x40404040, 0x40404000, 0x40404040, 0x40400000, 0x40400040, -+ 0x40400000, 0x40400040, 0x40404000, 0x40404040, 0x40404000, 0x40404040, -+ 0x40000000, 0x40000040, 0x40000000, 0x40000040, 0x40004000, 0x40004040, -+ 0x40004000, 0x40004040, 0x40000000, 0x40000040, 0x40000000, 0x40000040, -+ 0x40004000, 0x40004040, 0x40004000, 0x40004040, 0x40400000, 0x40400040, -+ 0x40400000, 0x40400040, 0x40404000, 0x40404040, 0x40404000, 0x40404040, -+ 0x40400000, 0x40400040, 0x40400000, 0x40400040, 0x40404000, 0x40404040, -+ 0x40404000, 0x40404040, 0x00000000, 0x00000040, 0x00000000, 0x00000040, -+ 0x00004000, 0x00004040, 0x00004000, 0x00004040, 0x00000000, 0x00000040, -+ 0x00000000, 0x00000040, 0x00004000, 0x00004040, 0x00004000, 0x00004040, -+ 0x00400000, 0x00400040, 0x00400000, 0x00400040, 0x00404000, 0x00404040, -+ 0x00404000, 0x00404040, 0x00400000, 0x00400040, 0x00400000, 0x00400040, -+ 0x00404000, 0x00404040, 0x00404000, 0x00404040, 0x00000000, 0x00000040, -+ 0x00000000, 0x00000040, 0x00004000, 0x00004040, 0x00004000, 0x00004040, -+ 0x00000000, 0x00000040, 0x00000000, 0x00000040, 0x00004000, 0x00004040, -+ 0x00004000, 0x00004040, 0x00400000, 0x00400040, 0x00400000, 0x00400040, -+ 0x00404000, 0x00404040, 0x00404000, 0x00404040, 0x00400000, 0x00400040, -+ 0x00400000, 0x00400040, 0x00404000, 0x00404040, 0x00404000, 0x00404040, -+ 0x40000000, 0x40000040, 0x40000000, 0x40000040, 0x40004000, 0x40004040, -+ 0x40004000, 0x40004040, 0x40000000, 0x40000040, 0x40000000, 0x40000040, -+ 0x40004000, 0x40004040, 0x40004000, 0x40004040, 0x40400000, 0x40400040, -+ 0x40400000, 0x40400040, 0x40404000, 0x40404040, 0x40404000, 0x40404040, -+ 0x40400000, 0x40400040, 0x40400000, 0x40400040, 0x40404000, 0x40404040, -+ 0x40404000, 0x40404040, 0x40000000, 0x40000040, 0x40000000, 0x40000040, -+ 0x40004000, 0x40004040, 0x40004000, 0x40004040, 0x40000000, 0x40000040, -+ 0x40000000, 0x40000040, 0x40004000, 0x40004040, 0x40004000, 0x40004040, -+ 0x40400000, 0x40400040, 0x40400000, 0x40400040, 0x40404000, 0x40404040, -+ 0x40404000, 0x40404040, 0x40400000, 0x40400040, 0x40400000, 0x40400040, -+ 0x40404000, 0x40404040, 0x40404000, 0x40404040, -+ }, -+ { -+ 0x00000000, 0x00000080, 0x00000000, 0x00000080, 0x00008000, 0x00008080, -+ 0x00008000, 0x00008080, 0x00000000, 0x00000080, 0x00000000, 0x00000080, -+ 0x00008000, 0x00008080, 0x00008000, 0x00008080, 0x00800000, 0x00800080, -+ 0x00800000, 0x00800080, 0x00808000, 0x00808080, 0x00808000, 0x00808080, -+ 0x00800000, 0x00800080, 0x00800000, 0x00800080, 0x00808000, 0x00808080, -+ 0x00808000, 0x00808080, 0x00000000, 0x00000080, 0x00000000, 0x00000080, -+ 0x00008000, 0x00008080, 0x00008000, 0x00008080, 0x00000000, 0x00000080, -+ 0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00008000, 0x00008080, -+ 0x00800000, 0x00800080, 0x00800000, 0x00800080, 0x00808000, 0x00808080, -+ 0x00808000, 0x00808080, 0x00800000, 0x00800080, 0x00800000, 0x00800080, -+ 0x00808000, 0x00808080, 0x00808000, 0x00808080, 0x80000000, 0x80000080, -+ 0x80000000, 0x80000080, 0x80008000, 0x80008080, 0x80008000, 0x80008080, -+ 0x80000000, 0x80000080, 0x80000000, 0x80000080, 0x80008000, 0x80008080, -+ 0x80008000, 0x80008080, 0x80800000, 0x80800080, 0x80800000, 0x80800080, -+ 0x80808000, 0x80808080, 0x80808000, 0x80808080, 0x80800000, 0x80800080, -+ 0x80800000, 0x80800080, 0x80808000, 0x80808080, 0x80808000, 0x80808080, -+ 0x80000000, 0x80000080, 0x80000000, 0x80000080, 0x80008000, 0x80008080, -+ 0x80008000, 0x80008080, 0x80000000, 0x80000080, 0x80000000, 0x80000080, -+ 0x80008000, 0x80008080, 0x80008000, 0x80008080, 0x80800000, 0x80800080, -+ 0x80800000, 0x80800080, 0x80808000, 0x80808080, 0x80808000, 0x80808080, -+ 0x80800000, 0x80800080, 0x80800000, 0x80800080, 0x80808000, 0x80808080, -+ 0x80808000, 0x80808080, 0x00000000, 0x00000080, 0x00000000, 0x00000080, -+ 0x00008000, 0x00008080, 0x00008000, 0x00008080, 0x00000000, 0x00000080, -+ 0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00008000, 0x00008080, -+ 0x00800000, 0x00800080, 0x00800000, 0x00800080, 0x00808000, 0x00808080, -+ 0x00808000, 0x00808080, 0x00800000, 0x00800080, 0x00800000, 0x00800080, -+ 0x00808000, 0x00808080, 0x00808000, 0x00808080, 0x00000000, 0x00000080, -+ 0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00008000, 0x00008080, -+ 0x00000000, 0x00000080, 0x00000000, 0x00000080, 0x00008000, 0x00008080, -+ 0x00008000, 0x00008080, 0x00800000, 0x00800080, 0x00800000, 0x00800080, -+ 0x00808000, 0x00808080, 0x00808000, 0x00808080, 0x00800000, 0x00800080, -+ 0x00800000, 0x00800080, 0x00808000, 0x00808080, 0x00808000, 0x00808080, -+ 0x80000000, 0x80000080, 0x80000000, 0x80000080, 0x80008000, 0x80008080, -+ 0x80008000, 0x80008080, 0x80000000, 0x80000080, 0x80000000, 0x80000080, -+ 0x80008000, 0x80008080, 0x80008000, 0x80008080, 0x80800000, 0x80800080, -+ 0x80800000, 0x80800080, 0x80808000, 0x80808080, 0x80808000, 0x80808080, -+ 0x80800000, 0x80800080, 0x80800000, 0x80800080, 0x80808000, 0x80808080, -+ 0x80808000, 0x80808080, 0x80000000, 0x80000080, 0x80000000, 0x80000080, -+ 0x80008000, 0x80008080, 0x80008000, 0x80008080, 0x80000000, 0x80000080, -+ 0x80000000, 0x80000080, 0x80008000, 0x80008080, 0x80008000, 0x80008080, -+ 0x80800000, 0x80800080, 0x80800000, 0x80800080, 0x80808000, 0x80808080, -+ 0x80808000, 0x80808080, 0x80800000, 0x80800080, 0x80800000, 0x80800080, -+ 0x80808000, 0x80808080, 0x80808000, 0x80808080, -+ }, -+}; -+ -+const uint32_t ip_maskr[8][256] = { -+ { -+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, -+ 0x00000001, 0x00000001, 0x00000100, 0x00000100, 0x00000101, 0x00000101, -+ 0x00000100, 0x00000100, 0x00000101, 0x00000101, 0x00000000, 0x00000000, -+ 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, -+ 0x00000100, 0x00000100, 0x00000101, 0x00000101, 0x00000100, 0x00000100, -+ 0x00000101, 0x00000101, 0x00010000, 0x00010000, 0x00010001, 0x00010001, -+ 0x00010000, 0x00010000, 0x00010001, 0x00010001, 0x00010100, 0x00010100, -+ 0x00010101, 0x00010101, 0x00010100, 0x00010100, 0x00010101, 0x00010101, -+ 0x00010000, 0x00010000, 0x00010001, 0x00010001, 0x00010000, 0x00010000, -+ 0x00010001, 0x00010001, 0x00010100, 0x00010100, 0x00010101, 0x00010101, -+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00000000, 0x00000000, -+ 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, -+ 0x00000100, 0x00000100, 0x00000101, 0x00000101, 0x00000100, 0x00000100, -+ 0x00000101, 0x00000101, 0x00000000, 0x00000000, 0x00000001, 0x00000001, -+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000100, 0x00000100, -+ 0x00000101, 0x00000101, 0x00000100, 0x00000100, 0x00000101, 0x00000101, -+ 0x00010000, 0x00010000, 0x00010001, 0x00010001, 0x00010000, 0x00010000, -+ 0x00010001, 0x00010001, 0x00010100, 0x00010100, 0x00010101, 0x00010101, -+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00010000, 0x00010000, -+ 0x00010001, 0x00010001, 0x00010000, 0x00010000, 0x00010001, 0x00010001, -+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00010100, 0x00010100, -+ 0x00010101, 0x00010101, 0x01000000, 0x01000000, 0x01000001, 0x01000001, -+ 0x01000000, 0x01000000, 0x01000001, 0x01000001, 0x01000100, 0x01000100, -+ 0x01000101, 0x01000101, 0x01000100, 0x01000100, 0x01000101, 0x01000101, -+ 0x01000000, 0x01000000, 0x01000001, 0x01000001, 0x01000000, 0x01000000, -+ 0x01000001, 0x01000001, 0x01000100, 0x01000100, 0x01000101, 0x01000101, -+ 0x01000100, 0x01000100, 0x01000101, 0x01000101, 0x01010000, 0x01010000, -+ 0x01010001, 0x01010001, 0x01010000, 0x01010000, 0x01010001, 0x01010001, -+ 0x01010100, 0x01010100, 0x01010101, 0x01010101, 0x01010100, 0x01010100, -+ 0x01010101, 0x01010101, 0x01010000, 0x01010000, 0x01010001, 0x01010001, -+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010100, 0x01010100, -+ 0x01010101, 0x01010101, 0x01010100, 0x01010100, 0x01010101, 0x01010101, -+ 0x01000000, 0x01000000, 0x01000001, 0x01000001, 0x01000000, 0x01000000, -+ 0x01000001, 0x01000001, 0x01000100, 0x01000100, 0x01000101, 0x01000101, -+ 0x01000100, 0x01000100, 0x01000101, 0x01000101, 0x01000000, 0x01000000, -+ 0x01000001, 0x01000001, 0x01000000, 0x01000000, 0x01000001, 0x01000001, -+ 0x01000100, 0x01000100, 0x01000101, 0x01000101, 0x01000100, 0x01000100, -+ 0x01000101, 0x01000101, 0x01010000, 0x01010000, 0x01010001, 0x01010001, -+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010100, 0x01010100, -+ 0x01010101, 0x01010101, 0x01010100, 0x01010100, 0x01010101, 0x01010101, -+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010000, 0x01010000, -+ 0x01010001, 0x01010001, 0x01010100, 0x01010100, 0x01010101, 0x01010101, -+ 0x01010100, 0x01010100, 0x01010101, 0x01010101, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000, -+ 0x00000002, 0x00000002, 0x00000200, 0x00000200, 0x00000202, 0x00000202, -+ 0x00000200, 0x00000200, 0x00000202, 0x00000202, 0x00000000, 0x00000000, -+ 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000002, -+ 0x00000200, 0x00000200, 0x00000202, 0x00000202, 0x00000200, 0x00000200, -+ 0x00000202, 0x00000202, 0x00020000, 0x00020000, 0x00020002, 0x00020002, -+ 0x00020000, 0x00020000, 0x00020002, 0x00020002, 0x00020200, 0x00020200, -+ 0x00020202, 0x00020202, 0x00020200, 0x00020200, 0x00020202, 0x00020202, -+ 0x00020000, 0x00020000, 0x00020002, 0x00020002, 0x00020000, 0x00020000, -+ 0x00020002, 0x00020002, 0x00020200, 0x00020200, 0x00020202, 0x00020202, -+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00000000, 0x00000000, -+ 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000002, -+ 0x00000200, 0x00000200, 0x00000202, 0x00000202, 0x00000200, 0x00000200, -+ 0x00000202, 0x00000202, 0x00000000, 0x00000000, 0x00000002, 0x00000002, -+ 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000200, 0x00000200, -+ 0x00000202, 0x00000202, 0x00000200, 0x00000200, 0x00000202, 0x00000202, -+ 0x00020000, 0x00020000, 0x00020002, 0x00020002, 0x00020000, 0x00020000, -+ 0x00020002, 0x00020002, 0x00020200, 0x00020200, 0x00020202, 0x00020202, -+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00020000, 0x00020000, -+ 0x00020002, 0x00020002, 0x00020000, 0x00020000, 0x00020002, 0x00020002, -+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00020200, 0x00020200, -+ 0x00020202, 0x00020202, 0x02000000, 0x02000000, 0x02000002, 0x02000002, -+ 0x02000000, 0x02000000, 0x02000002, 0x02000002, 0x02000200, 0x02000200, -+ 0x02000202, 0x02000202, 0x02000200, 0x02000200, 0x02000202, 0x02000202, -+ 0x02000000, 0x02000000, 0x02000002, 0x02000002, 0x02000000, 0x02000000, -+ 0x02000002, 0x02000002, 0x02000200, 0x02000200, 0x02000202, 0x02000202, -+ 0x02000200, 0x02000200, 0x02000202, 0x02000202, 0x02020000, 0x02020000, -+ 0x02020002, 0x02020002, 0x02020000, 0x02020000, 0x02020002, 0x02020002, -+ 0x02020200, 0x02020200, 0x02020202, 0x02020202, 0x02020200, 0x02020200, -+ 0x02020202, 0x02020202, 0x02020000, 0x02020000, 0x02020002, 0x02020002, -+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020200, 0x02020200, -+ 0x02020202, 0x02020202, 0x02020200, 0x02020200, 0x02020202, 0x02020202, -+ 0x02000000, 0x02000000, 0x02000002, 0x02000002, 0x02000000, 0x02000000, -+ 0x02000002, 0x02000002, 0x02000200, 0x02000200, 0x02000202, 0x02000202, -+ 0x02000200, 0x02000200, 0x02000202, 0x02000202, 0x02000000, 0x02000000, -+ 0x02000002, 0x02000002, 0x02000000, 0x02000000, 0x02000002, 0x02000002, -+ 0x02000200, 0x02000200, 0x02000202, 0x02000202, 0x02000200, 0x02000200, -+ 0x02000202, 0x02000202, 0x02020000, 0x02020000, 0x02020002, 0x02020002, -+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020200, 0x02020200, -+ 0x02020202, 0x02020202, 0x02020200, 0x02020200, 0x02020202, 0x02020202, -+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020000, 0x02020000, -+ 0x02020002, 0x02020002, 0x02020200, 0x02020200, 0x02020202, 0x02020202, -+ 0x02020200, 0x02020200, 0x02020202, 0x02020202, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000000, 0x00000000, -+ 0x00000004, 0x00000004, 0x00000400, 0x00000400, 0x00000404, 0x00000404, -+ 0x00000400, 0x00000400, 0x00000404, 0x00000404, 0x00000000, 0x00000000, -+ 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000004, 0x00000004, -+ 0x00000400, 0x00000400, 0x00000404, 0x00000404, 0x00000400, 0x00000400, -+ 0x00000404, 0x00000404, 0x00040000, 0x00040000, 0x00040004, 0x00040004, -+ 0x00040000, 0x00040000, 0x00040004, 0x00040004, 0x00040400, 0x00040400, -+ 0x00040404, 0x00040404, 0x00040400, 0x00040400, 0x00040404, 0x00040404, -+ 0x00040000, 0x00040000, 0x00040004, 0x00040004, 0x00040000, 0x00040000, -+ 0x00040004, 0x00040004, 0x00040400, 0x00040400, 0x00040404, 0x00040404, -+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00000000, 0x00000000, -+ 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000004, 0x00000004, -+ 0x00000400, 0x00000400, 0x00000404, 0x00000404, 0x00000400, 0x00000400, -+ 0x00000404, 0x00000404, 0x00000000, 0x00000000, 0x00000004, 0x00000004, -+ 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000400, 0x00000400, -+ 0x00000404, 0x00000404, 0x00000400, 0x00000400, 0x00000404, 0x00000404, -+ 0x00040000, 0x00040000, 0x00040004, 0x00040004, 0x00040000, 0x00040000, -+ 0x00040004, 0x00040004, 0x00040400, 0x00040400, 0x00040404, 0x00040404, -+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00040000, 0x00040000, -+ 0x00040004, 0x00040004, 0x00040000, 0x00040000, 0x00040004, 0x00040004, -+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00040400, 0x00040400, -+ 0x00040404, 0x00040404, 0x04000000, 0x04000000, 0x04000004, 0x04000004, -+ 0x04000000, 0x04000000, 0x04000004, 0x04000004, 0x04000400, 0x04000400, -+ 0x04000404, 0x04000404, 0x04000400, 0x04000400, 0x04000404, 0x04000404, -+ 0x04000000, 0x04000000, 0x04000004, 0x04000004, 0x04000000, 0x04000000, -+ 0x04000004, 0x04000004, 0x04000400, 0x04000400, 0x04000404, 0x04000404, -+ 0x04000400, 0x04000400, 0x04000404, 0x04000404, 0x04040000, 0x04040000, -+ 0x04040004, 0x04040004, 0x04040000, 0x04040000, 0x04040004, 0x04040004, -+ 0x04040400, 0x04040400, 0x04040404, 0x04040404, 0x04040400, 0x04040400, -+ 0x04040404, 0x04040404, 0x04040000, 0x04040000, 0x04040004, 0x04040004, -+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040400, 0x04040400, -+ 0x04040404, 0x04040404, 0x04040400, 0x04040400, 0x04040404, 0x04040404, -+ 0x04000000, 0x04000000, 0x04000004, 0x04000004, 0x04000000, 0x04000000, -+ 0x04000004, 0x04000004, 0x04000400, 0x04000400, 0x04000404, 0x04000404, -+ 0x04000400, 0x04000400, 0x04000404, 0x04000404, 0x04000000, 0x04000000, -+ 0x04000004, 0x04000004, 0x04000000, 0x04000000, 0x04000004, 0x04000004, -+ 0x04000400, 0x04000400, 0x04000404, 0x04000404, 0x04000400, 0x04000400, -+ 0x04000404, 0x04000404, 0x04040000, 0x04040000, 0x04040004, 0x04040004, -+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040400, 0x04040400, -+ 0x04040404, 0x04040404, 0x04040400, 0x04040400, 0x04040404, 0x04040404, -+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040000, 0x04040000, -+ 0x04040004, 0x04040004, 0x04040400, 0x04040400, 0x04040404, 0x04040404, -+ 0x04040400, 0x04040400, 0x04040404, 0x04040404, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000000, 0x00000000, -+ 0x00000008, 0x00000008, 0x00000800, 0x00000800, 0x00000808, 0x00000808, -+ 0x00000800, 0x00000800, 0x00000808, 0x00000808, 0x00000000, 0x00000000, -+ 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000008, 0x00000008, -+ 0x00000800, 0x00000800, 0x00000808, 0x00000808, 0x00000800, 0x00000800, -+ 0x00000808, 0x00000808, 0x00080000, 0x00080000, 0x00080008, 0x00080008, -+ 0x00080000, 0x00080000, 0x00080008, 0x00080008, 0x00080800, 0x00080800, -+ 0x00080808, 0x00080808, 0x00080800, 0x00080800, 0x00080808, 0x00080808, -+ 0x00080000, 0x00080000, 0x00080008, 0x00080008, 0x00080000, 0x00080000, -+ 0x00080008, 0x00080008, 0x00080800, 0x00080800, 0x00080808, 0x00080808, -+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00000000, 0x00000000, -+ 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000008, 0x00000008, -+ 0x00000800, 0x00000800, 0x00000808, 0x00000808, 0x00000800, 0x00000800, -+ 0x00000808, 0x00000808, 0x00000000, 0x00000000, 0x00000008, 0x00000008, -+ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000800, 0x00000800, -+ 0x00000808, 0x00000808, 0x00000800, 0x00000800, 0x00000808, 0x00000808, -+ 0x00080000, 0x00080000, 0x00080008, 0x00080008, 0x00080000, 0x00080000, -+ 0x00080008, 0x00080008, 0x00080800, 0x00080800, 0x00080808, 0x00080808, -+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00080000, 0x00080000, -+ 0x00080008, 0x00080008, 0x00080000, 0x00080000, 0x00080008, 0x00080008, -+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00080800, 0x00080800, -+ 0x00080808, 0x00080808, 0x08000000, 0x08000000, 0x08000008, 0x08000008, -+ 0x08000000, 0x08000000, 0x08000008, 0x08000008, 0x08000800, 0x08000800, -+ 0x08000808, 0x08000808, 0x08000800, 0x08000800, 0x08000808, 0x08000808, -+ 0x08000000, 0x08000000, 0x08000008, 0x08000008, 0x08000000, 0x08000000, -+ 0x08000008, 0x08000008, 0x08000800, 0x08000800, 0x08000808, 0x08000808, -+ 0x08000800, 0x08000800, 0x08000808, 0x08000808, 0x08080000, 0x08080000, -+ 0x08080008, 0x08080008, 0x08080000, 0x08080000, 0x08080008, 0x08080008, -+ 0x08080800, 0x08080800, 0x08080808, 0x08080808, 0x08080800, 0x08080800, -+ 0x08080808, 0x08080808, 0x08080000, 0x08080000, 0x08080008, 0x08080008, -+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080800, 0x08080800, -+ 0x08080808, 0x08080808, 0x08080800, 0x08080800, 0x08080808, 0x08080808, -+ 0x08000000, 0x08000000, 0x08000008, 0x08000008, 0x08000000, 0x08000000, -+ 0x08000008, 0x08000008, 0x08000800, 0x08000800, 0x08000808, 0x08000808, -+ 0x08000800, 0x08000800, 0x08000808, 0x08000808, 0x08000000, 0x08000000, -+ 0x08000008, 0x08000008, 0x08000000, 0x08000000, 0x08000008, 0x08000008, -+ 0x08000800, 0x08000800, 0x08000808, 0x08000808, 0x08000800, 0x08000800, -+ 0x08000808, 0x08000808, 0x08080000, 0x08080000, 0x08080008, 0x08080008, -+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080800, 0x08080800, -+ 0x08080808, 0x08080808, 0x08080800, 0x08080800, 0x08080808, 0x08080808, -+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080000, 0x08080000, -+ 0x08080008, 0x08080008, 0x08080800, 0x08080800, 0x08080808, 0x08080808, -+ 0x08080800, 0x08080800, 0x08080808, 0x08080808, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000000, 0x00000000, -+ 0x00000010, 0x00000010, 0x00001000, 0x00001000, 0x00001010, 0x00001010, -+ 0x00001000, 0x00001000, 0x00001010, 0x00001010, 0x00000000, 0x00000000, -+ 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000010, 0x00000010, -+ 0x00001000, 0x00001000, 0x00001010, 0x00001010, 0x00001000, 0x00001000, -+ 0x00001010, 0x00001010, 0x00100000, 0x00100000, 0x00100010, 0x00100010, -+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00101000, 0x00101000, -+ 0x00101010, 0x00101010, 0x00101000, 0x00101000, 0x00101010, 0x00101010, -+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00100000, 0x00100000, -+ 0x00100010, 0x00100010, 0x00101000, 0x00101000, 0x00101010, 0x00101010, -+ 0x00101000, 0x00101000, 0x00101010, 0x00101010, 0x00000000, 0x00000000, -+ 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000010, 0x00000010, -+ 0x00001000, 0x00001000, 0x00001010, 0x00001010, 0x00001000, 0x00001000, -+ 0x00001010, 0x00001010, 0x00000000, 0x00000000, 0x00000010, 0x00000010, -+ 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00001000, 0x00001000, -+ 0x00001010, 0x00001010, 0x00001000, 0x00001000, 0x00001010, 0x00001010, -+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00100000, 0x00100000, -+ 0x00100010, 0x00100010, 0x00101000, 0x00101000, 0x00101010, 0x00101010, -+ 0x00101000, 0x00101000, 0x00101010, 0x00101010, 0x00100000, 0x00100000, -+ 0x00100010, 0x00100010, 0x00100000, 0x00100000, 0x00100010, 0x00100010, -+ 0x00101000, 0x00101000, 0x00101010, 0x00101010, 0x00101000, 0x00101000, -+ 0x00101010, 0x00101010, 0x10000000, 0x10000000, 0x10000010, 0x10000010, -+ 0x10000000, 0x10000000, 0x10000010, 0x10000010, 0x10001000, 0x10001000, -+ 0x10001010, 0x10001010, 0x10001000, 0x10001000, 0x10001010, 0x10001010, -+ 0x10000000, 0x10000000, 0x10000010, 0x10000010, 0x10000000, 0x10000000, -+ 0x10000010, 0x10000010, 0x10001000, 0x10001000, 0x10001010, 0x10001010, -+ 0x10001000, 0x10001000, 0x10001010, 0x10001010, 0x10100000, 0x10100000, -+ 0x10100010, 0x10100010, 0x10100000, 0x10100000, 0x10100010, 0x10100010, -+ 0x10101000, 0x10101000, 0x10101010, 0x10101010, 0x10101000, 0x10101000, -+ 0x10101010, 0x10101010, 0x10100000, 0x10100000, 0x10100010, 0x10100010, -+ 0x10100000, 0x10100000, 0x10100010, 0x10100010, 0x10101000, 0x10101000, -+ 0x10101010, 0x10101010, 0x10101000, 0x10101000, 0x10101010, 0x10101010, -+ 0x10000000, 0x10000000, 0x10000010, 0x10000010, 0x10000000, 0x10000000, -+ 0x10000010, 0x10000010, 0x10001000, 0x10001000, 0x10001010, 0x10001010, -+ 0x10001000, 0x10001000, 0x10001010, 0x10001010, 0x10000000, 0x10000000, -+ 0x10000010, 0x10000010, 0x10000000, 0x10000000, 0x10000010, 0x10000010, -+ 0x10001000, 0x10001000, 0x10001010, 0x10001010, 0x10001000, 0x10001000, -+ 0x10001010, 0x10001010, 0x10100000, 0x10100000, 0x10100010, 0x10100010, -+ 0x10100000, 0x10100000, 0x10100010, 0x10100010, 0x10101000, 0x10101000, -+ 0x10101010, 0x10101010, 0x10101000, 0x10101000, 0x10101010, 0x10101010, -+ 0x10100000, 0x10100000, 0x10100010, 0x10100010, 0x10100000, 0x10100000, -+ 0x10100010, 0x10100010, 0x10101000, 0x10101000, 0x10101010, 0x10101010, -+ 0x10101000, 0x10101000, 0x10101010, 0x10101010, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000020, 0x00000020, 0x00000000, 0x00000000, -+ 0x00000020, 0x00000020, 0x00002000, 0x00002000, 0x00002020, 0x00002020, -+ 0x00002000, 0x00002000, 0x00002020, 0x00002020, 0x00000000, 0x00000000, -+ 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000020, 0x00000020, -+ 0x00002000, 0x00002000, 0x00002020, 0x00002020, 0x00002000, 0x00002000, -+ 0x00002020, 0x00002020, 0x00200000, 0x00200000, 0x00200020, 0x00200020, -+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00202000, 0x00202000, -+ 0x00202020, 0x00202020, 0x00202000, 0x00202000, 0x00202020, 0x00202020, -+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00200000, 0x00200000, -+ 0x00200020, 0x00200020, 0x00202000, 0x00202000, 0x00202020, 0x00202020, -+ 0x00202000, 0x00202000, 0x00202020, 0x00202020, 0x00000000, 0x00000000, -+ 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000020, 0x00000020, -+ 0x00002000, 0x00002000, 0x00002020, 0x00002020, 0x00002000, 0x00002000, -+ 0x00002020, 0x00002020, 0x00000000, 0x00000000, 0x00000020, 0x00000020, -+ 0x00000000, 0x00000000, 0x00000020, 0x00000020, 0x00002000, 0x00002000, -+ 0x00002020, 0x00002020, 0x00002000, 0x00002000, 0x00002020, 0x00002020, -+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00200000, 0x00200000, -+ 0x00200020, 0x00200020, 0x00202000, 0x00202000, 0x00202020, 0x00202020, -+ 0x00202000, 0x00202000, 0x00202020, 0x00202020, 0x00200000, 0x00200000, -+ 0x00200020, 0x00200020, 0x00200000, 0x00200000, 0x00200020, 0x00200020, -+ 0x00202000, 0x00202000, 0x00202020, 0x00202020, 0x00202000, 0x00202000, -+ 0x00202020, 0x00202020, 0x20000000, 0x20000000, 0x20000020, 0x20000020, -+ 0x20000000, 0x20000000, 0x20000020, 0x20000020, 0x20002000, 0x20002000, -+ 0x20002020, 0x20002020, 0x20002000, 0x20002000, 0x20002020, 0x20002020, -+ 0x20000000, 0x20000000, 0x20000020, 0x20000020, 0x20000000, 0x20000000, -+ 0x20000020, 0x20000020, 0x20002000, 0x20002000, 0x20002020, 0x20002020, -+ 0x20002000, 0x20002000, 0x20002020, 0x20002020, 0x20200000, 0x20200000, -+ 0x20200020, 0x20200020, 0x20200000, 0x20200000, 0x20200020, 0x20200020, -+ 0x20202000, 0x20202000, 0x20202020, 0x20202020, 0x20202000, 0x20202000, -+ 0x20202020, 0x20202020, 0x20200000, 0x20200000, 0x20200020, 0x20200020, -+ 0x20200000, 0x20200000, 0x20200020, 0x20200020, 0x20202000, 0x20202000, -+ 0x20202020, 0x20202020, 0x20202000, 0x20202000, 0x20202020, 0x20202020, -+ 0x20000000, 0x20000000, 0x20000020, 0x20000020, 0x20000000, 0x20000000, -+ 0x20000020, 0x20000020, 0x20002000, 0x20002000, 0x20002020, 0x20002020, -+ 0x20002000, 0x20002000, 0x20002020, 0x20002020, 0x20000000, 0x20000000, -+ 0x20000020, 0x20000020, 0x20000000, 0x20000000, 0x20000020, 0x20000020, -+ 0x20002000, 0x20002000, 0x20002020, 0x20002020, 0x20002000, 0x20002000, -+ 0x20002020, 0x20002020, 0x20200000, 0x20200000, 0x20200020, 0x20200020, -+ 0x20200000, 0x20200000, 0x20200020, 0x20200020, 0x20202000, 0x20202000, -+ 0x20202020, 0x20202020, 0x20202000, 0x20202000, 0x20202020, 0x20202020, -+ 0x20200000, 0x20200000, 0x20200020, 0x20200020, 0x20200000, 0x20200000, -+ 0x20200020, 0x20200020, 0x20202000, 0x20202000, 0x20202020, 0x20202020, -+ 0x20202000, 0x20202000, 0x20202020, 0x20202020, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00000000, 0x00000000, -+ 0x00000040, 0x00000040, 0x00004000, 0x00004000, 0x00004040, 0x00004040, -+ 0x00004000, 0x00004000, 0x00004040, 0x00004040, 0x00000000, 0x00000000, -+ 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000040, 0x00000040, -+ 0x00004000, 0x00004000, 0x00004040, 0x00004040, 0x00004000, 0x00004000, -+ 0x00004040, 0x00004040, 0x00400000, 0x00400000, 0x00400040, 0x00400040, -+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00404000, 0x00404000, -+ 0x00404040, 0x00404040, 0x00404000, 0x00404000, 0x00404040, 0x00404040, -+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00400000, 0x00400000, -+ 0x00400040, 0x00400040, 0x00404000, 0x00404000, 0x00404040, 0x00404040, -+ 0x00404000, 0x00404000, 0x00404040, 0x00404040, 0x00000000, 0x00000000, -+ 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000040, 0x00000040, -+ 0x00004000, 0x00004000, 0x00004040, 0x00004040, 0x00004000, 0x00004000, -+ 0x00004040, 0x00004040, 0x00000000, 0x00000000, 0x00000040, 0x00000040, -+ 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00004000, 0x00004000, -+ 0x00004040, 0x00004040, 0x00004000, 0x00004000, 0x00004040, 0x00004040, -+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00400000, 0x00400000, -+ 0x00400040, 0x00400040, 0x00404000, 0x00404000, 0x00404040, 0x00404040, -+ 0x00404000, 0x00404000, 0x00404040, 0x00404040, 0x00400000, 0x00400000, -+ 0x00400040, 0x00400040, 0x00400000, 0x00400000, 0x00400040, 0x00400040, -+ 0x00404000, 0x00404000, 0x00404040, 0x00404040, 0x00404000, 0x00404000, -+ 0x00404040, 0x00404040, 0x40000000, 0x40000000, 0x40000040, 0x40000040, -+ 0x40000000, 0x40000000, 0x40000040, 0x40000040, 0x40004000, 0x40004000, -+ 0x40004040, 0x40004040, 0x40004000, 0x40004000, 0x40004040, 0x40004040, -+ 0x40000000, 0x40000000, 0x40000040, 0x40000040, 0x40000000, 0x40000000, -+ 0x40000040, 0x40000040, 0x40004000, 0x40004000, 0x40004040, 0x40004040, -+ 0x40004000, 0x40004000, 0x40004040, 0x40004040, 0x40400000, 0x40400000, -+ 0x40400040, 0x40400040, 0x40400000, 0x40400000, 0x40400040, 0x40400040, -+ 0x40404000, 0x40404000, 0x40404040, 0x40404040, 0x40404000, 0x40404000, -+ 0x40404040, 0x40404040, 0x40400000, 0x40400000, 0x40400040, 0x40400040, -+ 0x40400000, 0x40400000, 0x40400040, 0x40400040, 0x40404000, 0x40404000, -+ 0x40404040, 0x40404040, 0x40404000, 0x40404000, 0x40404040, 0x40404040, -+ 0x40000000, 0x40000000, 0x40000040, 0x40000040, 0x40000000, 0x40000000, -+ 0x40000040, 0x40000040, 0x40004000, 0x40004000, 0x40004040, 0x40004040, -+ 0x40004000, 0x40004000, 0x40004040, 0x40004040, 0x40000000, 0x40000000, -+ 0x40000040, 0x40000040, 0x40000000, 0x40000000, 0x40000040, 0x40000040, -+ 0x40004000, 0x40004000, 0x40004040, 0x40004040, 0x40004000, 0x40004000, -+ 0x40004040, 0x40004040, 0x40400000, 0x40400000, 0x40400040, 0x40400040, -+ 0x40400000, 0x40400000, 0x40400040, 0x40400040, 0x40404000, 0x40404000, -+ 0x40404040, 0x40404040, 0x40404000, 0x40404000, 0x40404040, 0x40404040, -+ 0x40400000, 0x40400000, 0x40400040, 0x40400040, 0x40400000, 0x40400000, -+ 0x40400040, 0x40400040, 0x40404000, 0x40404000, 0x40404040, 0x40404040, -+ 0x40404000, 0x40404000, 0x40404040, 0x40404040, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00000000, 0x00000000, -+ 0x00000080, 0x00000080, 0x00008000, 0x00008000, 0x00008080, 0x00008080, -+ 0x00008000, 0x00008000, 0x00008080, 0x00008080, 0x00000000, 0x00000000, -+ 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x00000080, -+ 0x00008000, 0x00008000, 0x00008080, 0x00008080, 0x00008000, 0x00008000, -+ 0x00008080, 0x00008080, 0x00800000, 0x00800000, 0x00800080, 0x00800080, -+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00808000, 0x00808000, -+ 0x00808080, 0x00808080, 0x00808000, 0x00808000, 0x00808080, 0x00808080, -+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00800000, 0x00800000, -+ 0x00800080, 0x00800080, 0x00808000, 0x00808000, 0x00808080, 0x00808080, -+ 0x00808000, 0x00808000, 0x00808080, 0x00808080, 0x00000000, 0x00000000, -+ 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x00000080, -+ 0x00008000, 0x00008000, 0x00008080, 0x00008080, 0x00008000, 0x00008000, -+ 0x00008080, 0x00008080, 0x00000000, 0x00000000, 0x00000080, 0x00000080, -+ 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00008000, 0x00008000, -+ 0x00008080, 0x00008080, 0x00008000, 0x00008000, 0x00008080, 0x00008080, -+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00800000, 0x00800000, -+ 0x00800080, 0x00800080, 0x00808000, 0x00808000, 0x00808080, 0x00808080, -+ 0x00808000, 0x00808000, 0x00808080, 0x00808080, 0x00800000, 0x00800000, -+ 0x00800080, 0x00800080, 0x00800000, 0x00800000, 0x00800080, 0x00800080, -+ 0x00808000, 0x00808000, 0x00808080, 0x00808080, 0x00808000, 0x00808000, -+ 0x00808080, 0x00808080, 0x80000000, 0x80000000, 0x80000080, 0x80000080, -+ 0x80000000, 0x80000000, 0x80000080, 0x80000080, 0x80008000, 0x80008000, -+ 0x80008080, 0x80008080, 0x80008000, 0x80008000, 0x80008080, 0x80008080, -+ 0x80000000, 0x80000000, 0x80000080, 0x80000080, 0x80000000, 0x80000000, -+ 0x80000080, 0x80000080, 0x80008000, 0x80008000, 0x80008080, 0x80008080, -+ 0x80008000, 0x80008000, 0x80008080, 0x80008080, 0x80800000, 0x80800000, -+ 0x80800080, 0x80800080, 0x80800000, 0x80800000, 0x80800080, 0x80800080, -+ 0x80808000, 0x80808000, 0x80808080, 0x80808080, 0x80808000, 0x80808000, -+ 0x80808080, 0x80808080, 0x80800000, 0x80800000, 0x80800080, 0x80800080, -+ 0x80800000, 0x80800000, 0x80800080, 0x80800080, 0x80808000, 0x80808000, -+ 0x80808080, 0x80808080, 0x80808000, 0x80808000, 0x80808080, 0x80808080, -+ 0x80000000, 0x80000000, 0x80000080, 0x80000080, 0x80000000, 0x80000000, -+ 0x80000080, 0x80000080, 0x80008000, 0x80008000, 0x80008080, 0x80008080, -+ 0x80008000, 0x80008000, 0x80008080, 0x80008080, 0x80000000, 0x80000000, -+ 0x80000080, 0x80000080, 0x80000000, 0x80000000, 0x80000080, 0x80000080, -+ 0x80008000, 0x80008000, 0x80008080, 0x80008080, 0x80008000, 0x80008000, -+ 0x80008080, 0x80008080, 0x80800000, 0x80800000, 0x80800080, 0x80800080, -+ 0x80800000, 0x80800000, 0x80800080, 0x80800080, 0x80808000, 0x80808000, -+ 0x80808080, 0x80808080, 0x80808000, 0x80808000, 0x80808080, 0x80808080, -+ 0x80800000, 0x80800000, 0x80800080, 0x80800080, 0x80800000, 0x80800000, -+ 0x80800080, 0x80800080, 0x80808000, 0x80808000, 0x80808080, 0x80808080, -+ 0x80808000, 0x80808000, 0x80808080, 0x80808080, -+ }, -+}; -+ -+const uint32_t fp_maskl[8][256] = { -+ { -+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, -+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, -+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000, -+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000, -+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040, -+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000, -+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, -+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040, -+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, -+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, -+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000, -+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000, -+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040, -+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000, -+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, -+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040, -+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, -+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, -+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000, -+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000, -+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040, -+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000, -+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, -+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040, -+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, -+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, -+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000, -+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000, -+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040, -+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000, -+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, -+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040, -+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, -+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, -+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, 0x00000000, 0x40000000, -+ 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000, -+ 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040, -+ 0x00404040, 0x40404040, 0x00000000, 0x40000000, 0x00400000, 0x40400000, -+ 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, -+ 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040, -+ 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, -+ 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, -+ 0x00004040, 0x40004040, 0x00404040, 0x40404040, -+ }, -+ { -+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, -+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, -+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000, -+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000, -+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010, -+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000, -+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, -+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010, -+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, -+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, -+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000, -+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000, -+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010, -+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000, -+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, -+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010, -+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, -+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, -+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000, -+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000, -+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010, -+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000, -+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, -+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010, -+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, -+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, -+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000, -+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000, -+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010, -+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000, -+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, -+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010, -+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, -+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, -+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, 0x00000000, 0x10000000, -+ 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000, -+ 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010, -+ 0x00101010, 0x10101010, 0x00000000, 0x10000000, 0x00100000, 0x10100000, -+ 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, -+ 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010, -+ 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, -+ 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, -+ 0x00001010, 0x10001010, 0x00101010, 0x10101010, -+ }, -+ { -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, -+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, -+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, -+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, -+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, -+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, -+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, -+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, -+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, -+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, -+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, -+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, -+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, -+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, -+ 0x00040404, 0x04040404, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, -+ 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, -+ 0x00000404, 0x04000404, 0x00040404, 0x04040404, -+ }, -+ { -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, -+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, -+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, -+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, -+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, -+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, -+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, -+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, -+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, -+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, -+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, -+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, -+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, -+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, -+ 0x00010101, 0x01010101, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, -+ 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, -+ 0x00000101, 0x01000101, 0x00010101, 0x01010101, -+ }, -+ { -+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, -+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, -+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000, -+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, -+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, -+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000, -+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, -+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, -+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, -+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, -+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000, -+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, -+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, -+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000, -+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, -+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, -+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, -+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, -+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000, -+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, -+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, -+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000, -+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, -+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, -+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, -+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, -+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000, -+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, -+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, -+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000, -+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, -+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, -+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, -+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, -+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, 0x00000000, 0x80000000, -+ 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, -+ 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, -+ 0x00808080, 0x80808080, 0x00000000, 0x80000000, 0x00800000, 0x80800000, -+ 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, -+ 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, -+ 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, -+ 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, -+ 0x00008080, 0x80008080, 0x00808080, 0x80808080, -+ }, -+ { -+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, -+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, -+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000, -+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000, -+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020, -+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000, -+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, -+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020, -+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, -+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, -+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000, -+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000, -+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020, -+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000, -+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, -+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020, -+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, -+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, -+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000, -+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000, -+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020, -+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000, -+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, -+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020, -+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, -+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, -+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000, -+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000, -+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020, -+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000, -+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, -+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020, -+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, -+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, -+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, 0x00000000, 0x20000000, -+ 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000, -+ 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020, -+ 0x00202020, 0x20202020, 0x00000000, 0x20000000, 0x00200000, 0x20200000, -+ 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, -+ 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020, -+ 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, -+ 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, -+ 0x00002020, 0x20002020, 0x00202020, 0x20202020, -+ }, -+ { -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, -+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808, -+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, -+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, -+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808, -+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, -+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, -+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808, -+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, -+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, -+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808, -+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, -+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, -+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808, -+ 0x00080808, 0x08080808, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, -+ 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, -+ 0x00000808, 0x08000808, 0x00080808, 0x08080808, -+ }, -+ { -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, -+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, -+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, -+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, -+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, -+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, -+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, -+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, -+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, -+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, -+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, -+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, -+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, -+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, -+ 0x00020202, 0x02020202, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, -+ 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, -+ 0x00000202, 0x02000202, 0x00020202, 0x02020202, -+ }, -+}; -+ -+const uint32_t fp_maskr[8][256] = { -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x40000000, -+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, -+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, -+ 0x40000000, 0x40000000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, -+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, -+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, -+ 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000, -+ 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000, -+ 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x00004000, 0x00004000, -+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, -+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, -+ 0x00004000, 0x00004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000, -+ 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000, -+ 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000, 0x40004000, -+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, -+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, -+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x40404000, 0x40404000, -+ 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000, -+ 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000, 0x40404000, -+ 0x40404000, 0x40404000, 0x00000040, 0x00000040, 0x00000040, 0x00000040, -+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, -+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, -+ 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040, -+ 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x40000040, -+ 0x40000040, 0x40000040, 0x40000040, 0x40000040, 0x00400040, 0x00400040, -+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, -+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, -+ 0x00400040, 0x00400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040, -+ 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040, -+ 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040, 0x40400040, -+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, -+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, -+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x40004040, 0x40004040, -+ 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040, -+ 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040, 0x40004040, -+ 0x40004040, 0x40004040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, -+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, -+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, -+ 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040, -+ 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040, 0x40404040, -+ 0x40404040, 0x40404040, 0x40404040, 0x40404040, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000000, 0x10000000, -+ 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, -+ 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, -+ 0x10000000, 0x10000000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, -+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, -+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, -+ 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000, -+ 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x10100000, -+ 0x10100000, 0x10100000, 0x10100000, 0x10100000, 0x00001000, 0x00001000, -+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, -+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, -+ 0x00001000, 0x00001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000, -+ 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000, -+ 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000, 0x10001000, -+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, -+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, -+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x10101000, 0x10101000, -+ 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000, -+ 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000, 0x10101000, -+ 0x10101000, 0x10101000, 0x00000010, 0x00000010, 0x00000010, 0x00000010, -+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, -+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, -+ 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010, -+ 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x10000010, -+ 0x10000010, 0x10000010, 0x10000010, 0x10000010, 0x00100010, 0x00100010, -+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, -+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, -+ 0x00100010, 0x00100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010, -+ 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010, -+ 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010, 0x10100010, -+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, -+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, -+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x10001010, 0x10001010, -+ 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010, -+ 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010, 0x10001010, -+ 0x10001010, 0x10001010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, -+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, -+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, -+ 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, -+ 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, -+ 0x10101010, 0x10101010, 0x10101010, 0x10101010, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000000, 0x04000000, -+ 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, -+ 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, -+ 0x04000000, 0x04000000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, -+ 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, -+ 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, -+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, -+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, -+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x00000400, 0x00000400, -+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, -+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, -+ 0x00000400, 0x00000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400, -+ 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400, -+ 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000400, -+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, -+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, -+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x04040400, 0x04040400, -+ 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, -+ 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, -+ 0x04040400, 0x04040400, 0x00000004, 0x00000004, 0x00000004, 0x00000004, -+ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004, -+ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004, -+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, -+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, -+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x00040004, 0x00040004, -+ 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, -+ 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, -+ 0x00040004, 0x00040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004, -+ 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004, -+ 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040004, -+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, -+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, -+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x04000404, 0x04000404, -+ 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, -+ 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, -+ 0x04000404, 0x04000404, 0x00040404, 0x00040404, 0x00040404, 0x00040404, -+ 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404, -+ 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x00040404, -+ 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, -+ 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, -+ 0x04040404, 0x04040404, 0x04040404, 0x04040404, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000000, 0x01000000, -+ 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, -+ 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, -+ 0x01000000, 0x01000000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, -+ 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, -+ 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, -+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, -+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, -+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x00000100, 0x00000100, -+ 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, -+ 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, -+ 0x00000100, 0x00000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100, -+ 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100, -+ 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000100, -+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, -+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, -+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x01010100, 0x01010100, -+ 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, -+ 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, -+ 0x01010100, 0x01010100, 0x00000001, 0x00000001, 0x00000001, 0x00000001, -+ 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, -+ 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, -+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, -+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, -+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x00010001, 0x00010001, -+ 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, -+ 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, -+ 0x00010001, 0x00010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001, -+ 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001, -+ 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010001, -+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, -+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, -+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x01000101, 0x01000101, -+ 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, -+ 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, -+ 0x01000101, 0x01000101, 0x00010101, 0x00010101, 0x00010101, 0x00010101, -+ 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101, -+ 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x00010101, -+ 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, -+ 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, -+ 0x01010101, 0x01010101, 0x01010101, 0x01010101, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x80000000, -+ 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, -+ 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, -+ 0x80000000, 0x80000000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, -+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, -+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, -+ 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000, -+ 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x80800000, -+ 0x80800000, 0x80800000, 0x80800000, 0x80800000, 0x00008000, 0x00008000, -+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, -+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, -+ 0x00008000, 0x00008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000, -+ 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000, -+ 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000, 0x80008000, -+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, -+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, -+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x80808000, 0x80808000, -+ 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000, -+ 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000, 0x80808000, -+ 0x80808000, 0x80808000, 0x00000080, 0x00000080, 0x00000080, 0x00000080, -+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, -+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, -+ 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080, -+ 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x80000080, -+ 0x80000080, 0x80000080, 0x80000080, 0x80000080, 0x00800080, 0x00800080, -+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, -+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, -+ 0x00800080, 0x00800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080, -+ 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080, -+ 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080, 0x80800080, -+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, -+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, -+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x80008080, 0x80008080, -+ 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080, -+ 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080, 0x80008080, -+ 0x80008080, 0x80008080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, -+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, -+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, -+ 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, -+ 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, -+ 0x80808080, 0x80808080, 0x80808080, 0x80808080, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20000000, 0x20000000, -+ 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000, -+ 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000, 0x20000000, -+ 0x20000000, 0x20000000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, -+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, -+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, -+ 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000, -+ 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x20200000, -+ 0x20200000, 0x20200000, 0x20200000, 0x20200000, 0x00002000, 0x00002000, -+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, -+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, -+ 0x00002000, 0x00002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000, -+ 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000, -+ 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000, 0x20002000, -+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, -+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, -+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x20202000, 0x20202000, -+ 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000, -+ 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000, 0x20202000, -+ 0x20202000, 0x20202000, 0x00000020, 0x00000020, 0x00000020, 0x00000020, -+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, -+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, -+ 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020, -+ 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x20000020, -+ 0x20000020, 0x20000020, 0x20000020, 0x20000020, 0x00200020, 0x00200020, -+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, -+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, -+ 0x00200020, 0x00200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020, -+ 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020, -+ 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020, 0x20200020, -+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, -+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, -+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x20002020, 0x20002020, -+ 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020, -+ 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020, 0x20002020, -+ 0x20002020, 0x20002020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, -+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, -+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, -+ 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, -+ 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, -+ 0x20202020, 0x20202020, 0x20202020, 0x20202020, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08000000, 0x08000000, -+ 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, -+ 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, -+ 0x08000000, 0x08000000, 0x00080000, 0x00080000, 0x00080000, 0x00080000, -+ 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000, -+ 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000, -+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, -+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, -+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x00000800, 0x00000800, -+ 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, -+ 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, -+ 0x00000800, 0x00000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800, -+ 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800, -+ 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000800, -+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, -+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, -+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x08080800, 0x08080800, -+ 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, -+ 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, -+ 0x08080800, 0x08080800, 0x00000008, 0x00000008, 0x00000008, 0x00000008, -+ 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, -+ 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008, -+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, -+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, -+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x00080008, 0x00080008, -+ 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, -+ 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, -+ 0x00080008, 0x00080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008, -+ 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008, -+ 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080008, -+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, -+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, -+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x08000808, 0x08000808, -+ 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, -+ 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, -+ 0x08000808, 0x08000808, 0x00080808, 0x00080808, 0x00080808, 0x00080808, -+ 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808, -+ 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x00080808, -+ 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, -+ 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, -+ 0x08080808, 0x08080808, 0x08080808, 0x08080808, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02000000, 0x02000000, -+ 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, -+ 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, -+ 0x02000000, 0x02000000, 0x00020000, 0x00020000, 0x00020000, 0x00020000, -+ 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000, -+ 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000, -+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, -+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, -+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x00000200, 0x00000200, -+ 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, -+ 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, -+ 0x00000200, 0x00000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200, -+ 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200, -+ 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000200, -+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, -+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, -+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x02020200, 0x02020200, -+ 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, -+ 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, -+ 0x02020200, 0x02020200, 0x00000002, 0x00000002, 0x00000002, 0x00000002, -+ 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, -+ 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, -+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, -+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, -+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x00020002, 0x00020002, -+ 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, -+ 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, -+ 0x00020002, 0x00020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002, -+ 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002, -+ 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020002, -+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, -+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, -+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x02000202, 0x02000202, -+ 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, -+ 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, -+ 0x02000202, 0x02000202, 0x00020202, 0x00020202, 0x00020202, 0x00020202, -+ 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202, -+ 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x00020202, -+ 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, -+ 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, -+ 0x02020202, 0x02020202, 0x02020202, 0x02020202, -+ }, -+}; -+ -+const uint32_t key_perm_maskl[8][128] = { -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010, -+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, -+ 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010, -+ 0x00000010, 0x00000010, 0x00001000, 0x00001000, 0x00001000, 0x00001000, -+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, -+ 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, 0x00001000, -+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, -+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00001010, -+ 0x00001010, 0x00001010, 0x00001010, 0x00001010, 0x00100000, 0x00100000, -+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, -+ 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, -+ 0x00100000, 0x00100000, 0x00100010, 0x00100010, 0x00100010, 0x00100010, -+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, -+ 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, 0x00100010, -+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, -+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101000, -+ 0x00101000, 0x00101000, 0x00101000, 0x00101000, 0x00101010, 0x00101010, -+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, -+ 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, 0x00101010, -+ 0x00101010, 0x00101010, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0x00000020, -+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, -+ 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, -+ 0x00000020, 0x00000020, 0x00002000, 0x00002000, 0x00002000, 0x00002000, -+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, -+ 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, -+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, -+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00002020, -+ 0x00002020, 0x00002020, 0x00002020, 0x00002020, 0x00200000, 0x00200000, -+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, -+ 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000, -+ 0x00200000, 0x00200000, 0x00200020, 0x00200020, 0x00200020, 0x00200020, -+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, -+ 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, 0x00200020, -+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, -+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202000, -+ 0x00202000, 0x00202000, 0x00202000, 0x00202000, 0x00202020, 0x00202020, -+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, -+ 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, 0x00202020, -+ 0x00202020, 0x00202020, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000040, -+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, -+ 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0x00000040, -+ 0x00000040, 0x00000040, 0x00004000, 0x00004000, 0x00004000, 0x00004000, -+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, -+ 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, 0x00004000, -+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, -+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00004040, -+ 0x00004040, 0x00004040, 0x00004040, 0x00004040, 0x00400000, 0x00400000, -+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, -+ 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, -+ 0x00400000, 0x00400000, 0x00400040, 0x00400040, 0x00400040, 0x00400040, -+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, -+ 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, 0x00400040, -+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, -+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404000, -+ 0x00404000, 0x00404000, 0x00404000, 0x00404000, 0x00404040, 0x00404040, -+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, -+ 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, 0x00404040, -+ 0x00404040, 0x00404040, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000080, -+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, -+ 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080, -+ 0x00000080, 0x00000080, 0x00008000, 0x00008000, 0x00008000, 0x00008000, -+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, -+ 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00008000, -+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, -+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00008080, -+ 0x00008080, 0x00008080, 0x00008080, 0x00008080, 0x00800000, 0x00800000, -+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, -+ 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, -+ 0x00800000, 0x00800000, 0x00800080, 0x00800080, 0x00800080, 0x00800080, -+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, -+ 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, 0x00800080, -+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, -+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808000, -+ 0x00808000, 0x00808000, 0x00808000, 0x00808000, 0x00808080, 0x00808080, -+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, -+ 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, 0x00808080, -+ 0x00808080, 0x00808080, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, -+ 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000100, 0x00000100, -+ 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, 0x00000100, -+ 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, 0x00000101, -+ 0x00000101, 0x00000101, 0x00010000, 0x00010000, 0x00010000, 0x00010000, -+ 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010001, 0x00010001, -+ 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00010001, -+ 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, -+ 0x00010100, 0x00010100, 0x00010101, 0x00010101, 0x00010101, 0x00010101, -+ 0x00010101, 0x00010101, 0x00010101, 0x00010101, 0x01000000, 0x01000000, -+ 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000, -+ 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, 0x01000001, -+ 0x01000001, 0x01000001, 0x01000100, 0x01000100, 0x01000100, 0x01000100, -+ 0x01000100, 0x01000100, 0x01000100, 0x01000100, 0x01000101, 0x01000101, -+ 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, 0x01000101, -+ 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, -+ 0x01010000, 0x01010000, 0x01010001, 0x01010001, 0x01010001, 0x01010001, -+ 0x01010001, 0x01010001, 0x01010001, 0x01010001, 0x01010100, 0x01010100, -+ 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, -+ 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, 0x01010101, -+ 0x01010101, 0x01010101, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000002, 0x00000002, -+ 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000200, 0x00000200, -+ 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0x00000200, -+ 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, -+ 0x00000202, 0x00000202, 0x00020000, 0x00020000, 0x00020000, 0x00020000, -+ 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020002, 0x00020002, -+ 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, 0x00020002, -+ 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, 0x00020200, -+ 0x00020200, 0x00020200, 0x00020202, 0x00020202, 0x00020202, 0x00020202, -+ 0x00020202, 0x00020202, 0x00020202, 0x00020202, 0x02000000, 0x02000000, -+ 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, -+ 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, 0x02000002, -+ 0x02000002, 0x02000002, 0x02000200, 0x02000200, 0x02000200, 0x02000200, -+ 0x02000200, 0x02000200, 0x02000200, 0x02000200, 0x02000202, 0x02000202, -+ 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, 0x02000202, -+ 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, -+ 0x02020000, 0x02020000, 0x02020002, 0x02020002, 0x02020002, 0x02020002, -+ 0x02020002, 0x02020002, 0x02020002, 0x02020002, 0x02020200, 0x02020200, -+ 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200, -+ 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, -+ 0x02020202, 0x02020202, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004, 0x00000004, -+ 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000400, 0x00000400, -+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, -+ 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, -+ 0x00000404, 0x00000404, 0x00040000, 0x00040000, 0x00040000, 0x00040000, -+ 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040004, 0x00040004, -+ 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, 0x00040004, -+ 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, 0x00040400, -+ 0x00040400, 0x00040400, 0x00040404, 0x00040404, 0x00040404, 0x00040404, -+ 0x00040404, 0x00040404, 0x00040404, 0x00040404, 0x04000000, 0x04000000, -+ 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000, -+ 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, 0x04000004, -+ 0x04000004, 0x04000004, 0x04000400, 0x04000400, 0x04000400, 0x04000400, -+ 0x04000400, 0x04000400, 0x04000400, 0x04000400, 0x04000404, 0x04000404, -+ 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, 0x04000404, -+ 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, -+ 0x04040000, 0x04040000, 0x04040004, 0x04040004, 0x04040004, 0x04040004, -+ 0x04040004, 0x04040004, 0x04040004, 0x04040004, 0x04040400, 0x04040400, -+ 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, 0x04040400, -+ 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, -+ 0x04040404, 0x04040404, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00000008, -+ 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000800, 0x00000800, -+ 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800, -+ 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, -+ 0x00000808, 0x00000808, 0x00080000, 0x00080000, 0x00080000, 0x00080000, -+ 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080008, 0x00080008, -+ 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, 0x00080008, -+ 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, 0x00080800, -+ 0x00080800, 0x00080800, 0x00080808, 0x00080808, 0x00080808, 0x00080808, -+ 0x00080808, 0x00080808, 0x00080808, 0x00080808, 0x08000000, 0x08000000, -+ 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0x08000000, -+ 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, 0x08000008, -+ 0x08000008, 0x08000008, 0x08000800, 0x08000800, 0x08000800, 0x08000800, -+ 0x08000800, 0x08000800, 0x08000800, 0x08000800, 0x08000808, 0x08000808, -+ 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, 0x08000808, -+ 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, -+ 0x08080000, 0x08080000, 0x08080008, 0x08080008, 0x08080008, 0x08080008, -+ 0x08080008, 0x08080008, 0x08080008, 0x08080008, 0x08080800, 0x08080800, -+ 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, 0x08080800, -+ 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, -+ 0x08080808, 0x08080808, -+ }, -+}; -+ -+const uint32_t key_perm_maskr[8][128] = { -+ { -+ 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010, -+ 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001, -+ 0x00000011, 0x00100011, 0x00001011, 0x00101011, 0x00000000, 0x00100000, -+ 0x00001000, 0x00101000, 0x00000010, 0x00100010, 0x00001010, 0x00101010, -+ 0x00000001, 0x00100001, 0x00001001, 0x00101001, 0x00000011, 0x00100011, -+ 0x00001011, 0x00101011, 0x00000000, 0x00100000, 0x00001000, 0x00101000, -+ 0x00000010, 0x00100010, 0x00001010, 0x00101010, 0x00000001, 0x00100001, -+ 0x00001001, 0x00101001, 0x00000011, 0x00100011, 0x00001011, 0x00101011, -+ 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010, -+ 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001, -+ 0x00000011, 0x00100011, 0x00001011, 0x00101011, 0x00000000, 0x00100000, -+ 0x00001000, 0x00101000, 0x00000010, 0x00100010, 0x00001010, 0x00101010, -+ 0x00000001, 0x00100001, 0x00001001, 0x00101001, 0x00000011, 0x00100011, -+ 0x00001011, 0x00101011, 0x00000000, 0x00100000, 0x00001000, 0x00101000, -+ 0x00000010, 0x00100010, 0x00001010, 0x00101010, 0x00000001, 0x00100001, -+ 0x00001001, 0x00101001, 0x00000011, 0x00100011, 0x00001011, 0x00101011, -+ 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010, -+ 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001, -+ 0x00000011, 0x00100011, 0x00001011, 0x00101011, 0x00000000, 0x00100000, -+ 0x00001000, 0x00101000, 0x00000010, 0x00100010, 0x00001010, 0x00101010, -+ 0x00000001, 0x00100001, 0x00001001, 0x00101001, 0x00000011, 0x00100011, -+ 0x00001011, 0x00101011, -+ }, -+ { -+ 0x00000000, 0x00200000, 0x00002000, 0x00202000, 0x00000020, 0x00200020, -+ 0x00002020, 0x00202020, 0x00000002, 0x00200002, 0x00002002, 0x00202002, -+ 0x00000022, 0x00200022, 0x00002022, 0x00202022, 0x00000000, 0x00200000, -+ 0x00002000, 0x00202000, 0x00000020, 0x00200020, 0x00002020, 0x00202020, -+ 0x00000002, 0x00200002, 0x00002002, 0x00202002, 0x00000022, 0x00200022, -+ 0x00002022, 0x00202022, 0x00000000, 0x00200000, 0x00002000, 0x00202000, -+ 0x00000020, 0x00200020, 0x00002020, 0x00202020, 0x00000002, 0x00200002, -+ 0x00002002, 0x00202002, 0x00000022, 0x00200022, 0x00002022, 0x00202022, -+ 0x00000000, 0x00200000, 0x00002000, 0x00202000, 0x00000020, 0x00200020, -+ 0x00002020, 0x00202020, 0x00000002, 0x00200002, 0x00002002, 0x00202002, -+ 0x00000022, 0x00200022, 0x00002022, 0x00202022, 0x00000000, 0x00200000, -+ 0x00002000, 0x00202000, 0x00000020, 0x00200020, 0x00002020, 0x00202020, -+ 0x00000002, 0x00200002, 0x00002002, 0x00202002, 0x00000022, 0x00200022, -+ 0x00002022, 0x00202022, 0x00000000, 0x00200000, 0x00002000, 0x00202000, -+ 0x00000020, 0x00200020, 0x00002020, 0x00202020, 0x00000002, 0x00200002, -+ 0x00002002, 0x00202002, 0x00000022, 0x00200022, 0x00002022, 0x00202022, -+ 0x00000000, 0x00200000, 0x00002000, 0x00202000, 0x00000020, 0x00200020, -+ 0x00002020, 0x00202020, 0x00000002, 0x00200002, 0x00002002, 0x00202002, -+ 0x00000022, 0x00200022, 0x00002022, 0x00202022, 0x00000000, 0x00200000, -+ 0x00002000, 0x00202000, 0x00000020, 0x00200020, 0x00002020, 0x00202020, -+ 0x00000002, 0x00200002, 0x00002002, 0x00202002, 0x00000022, 0x00200022, -+ 0x00002022, 0x00202022, -+ }, -+ { -+ 0x00000000, 0x00400000, 0x00004000, 0x00404000, 0x00000040, 0x00400040, -+ 0x00004040, 0x00404040, 0x00000004, 0x00400004, 0x00004004, 0x00404004, -+ 0x00000044, 0x00400044, 0x00004044, 0x00404044, 0x00000000, 0x00400000, -+ 0x00004000, 0x00404000, 0x00000040, 0x00400040, 0x00004040, 0x00404040, -+ 0x00000004, 0x00400004, 0x00004004, 0x00404004, 0x00000044, 0x00400044, -+ 0x00004044, 0x00404044, 0x00000000, 0x00400000, 0x00004000, 0x00404000, -+ 0x00000040, 0x00400040, 0x00004040, 0x00404040, 0x00000004, 0x00400004, -+ 0x00004004, 0x00404004, 0x00000044, 0x00400044, 0x00004044, 0x00404044, -+ 0x00000000, 0x00400000, 0x00004000, 0x00404000, 0x00000040, 0x00400040, -+ 0x00004040, 0x00404040, 0x00000004, 0x00400004, 0x00004004, 0x00404004, -+ 0x00000044, 0x00400044, 0x00004044, 0x00404044, 0x00000000, 0x00400000, -+ 0x00004000, 0x00404000, 0x00000040, 0x00400040, 0x00004040, 0x00404040, -+ 0x00000004, 0x00400004, 0x00004004, 0x00404004, 0x00000044, 0x00400044, -+ 0x00004044, 0x00404044, 0x00000000, 0x00400000, 0x00004000, 0x00404000, -+ 0x00000040, 0x00400040, 0x00004040, 0x00404040, 0x00000004, 0x00400004, -+ 0x00004004, 0x00404004, 0x00000044, 0x00400044, 0x00004044, 0x00404044, -+ 0x00000000, 0x00400000, 0x00004000, 0x00404000, 0x00000040, 0x00400040, -+ 0x00004040, 0x00404040, 0x00000004, 0x00400004, 0x00004004, 0x00404004, -+ 0x00000044, 0x00400044, 0x00004044, 0x00404044, 0x00000000, 0x00400000, -+ 0x00004000, 0x00404000, 0x00000040, 0x00400040, 0x00004040, 0x00404040, -+ 0x00000004, 0x00400004, 0x00004004, 0x00404004, 0x00000044, 0x00400044, -+ 0x00004044, 0x00404044, -+ }, -+ { -+ 0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080, -+ 0x00008080, 0x00808080, 0x00000008, 0x00800008, 0x00008008, 0x00808008, -+ 0x00000088, 0x00800088, 0x00008088, 0x00808088, 0x00000000, 0x00800000, -+ 0x00008000, 0x00808000, 0x00000080, 0x00800080, 0x00008080, 0x00808080, -+ 0x00000008, 0x00800008, 0x00008008, 0x00808008, 0x00000088, 0x00800088, -+ 0x00008088, 0x00808088, 0x00000000, 0x00800000, 0x00008000, 0x00808000, -+ 0x00000080, 0x00800080, 0x00008080, 0x00808080, 0x00000008, 0x00800008, -+ 0x00008008, 0x00808008, 0x00000088, 0x00800088, 0x00008088, 0x00808088, -+ 0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080, -+ 0x00008080, 0x00808080, 0x00000008, 0x00800008, 0x00008008, 0x00808008, -+ 0x00000088, 0x00800088, 0x00008088, 0x00808088, 0x00000000, 0x00800000, -+ 0x00008000, 0x00808000, 0x00000080, 0x00800080, 0x00008080, 0x00808080, -+ 0x00000008, 0x00800008, 0x00008008, 0x00808008, 0x00000088, 0x00800088, -+ 0x00008088, 0x00808088, 0x00000000, 0x00800000, 0x00008000, 0x00808000, -+ 0x00000080, 0x00800080, 0x00008080, 0x00808080, 0x00000008, 0x00800008, -+ 0x00008008, 0x00808008, 0x00000088, 0x00800088, 0x00008088, 0x00808088, -+ 0x00000000, 0x00800000, 0x00008000, 0x00808000, 0x00000080, 0x00800080, -+ 0x00008080, 0x00808080, 0x00000008, 0x00800008, 0x00008008, 0x00808008, -+ 0x00000088, 0x00800088, 0x00008088, 0x00808088, 0x00000000, 0x00800000, -+ 0x00008000, 0x00808000, 0x00000080, 0x00800080, 0x00008080, 0x00808080, -+ 0x00000008, 0x00800008, 0x00008008, 0x00808008, 0x00000088, 0x00800088, -+ 0x00008088, 0x00808088, -+ }, -+ { -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, 0x00000000, 0x01000000, 0x00010000, 0x01010000, -+ 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000000, 0x01000000, -+ 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, -+ 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, -+ 0x00010100, 0x01010100, -+ }, -+ { -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, 0x00000000, 0x02000000, 0x00020000, 0x02020000, -+ 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000000, 0x02000000, -+ 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, -+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, -+ 0x00020200, 0x02020200, -+ }, -+ { -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, 0x00000000, 0x04000000, 0x00040000, 0x04040000, -+ 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000000, 0x04000000, -+ 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, -+ 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, -+ 0x00040400, 0x04040400, -+ }, -+ { -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, 0x00000000, 0x08000000, 0x00080000, 0x08080000, -+ 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000000, 0x08000000, -+ 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, -+ 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, -+ 0x00080800, 0x08080800, -+ }, -+}; -+ -+const uint32_t comp_maskl[8][128] = { -+ { -+ 0x00000000, 0x00000010, 0x00004000, 0x00004010, 0x00040000, 0x00040010, -+ 0x00044000, 0x00044010, 0x00000100, 0x00000110, 0x00004100, 0x00004110, -+ 0x00040100, 0x00040110, 0x00044100, 0x00044110, 0x00020000, 0x00020010, -+ 0x00024000, 0x00024010, 0x00060000, 0x00060010, 0x00064000, 0x00064010, -+ 0x00020100, 0x00020110, 0x00024100, 0x00024110, 0x00060100, 0x00060110, -+ 0x00064100, 0x00064110, 0x00000001, 0x00000011, 0x00004001, 0x00004011, -+ 0x00040001, 0x00040011, 0x00044001, 0x00044011, 0x00000101, 0x00000111, -+ 0x00004101, 0x00004111, 0x00040101, 0x00040111, 0x00044101, 0x00044111, -+ 0x00020001, 0x00020011, 0x00024001, 0x00024011, 0x00060001, 0x00060011, -+ 0x00064001, 0x00064011, 0x00020101, 0x00020111, 0x00024101, 0x00024111, -+ 0x00060101, 0x00060111, 0x00064101, 0x00064111, 0x00080000, 0x00080010, -+ 0x00084000, 0x00084010, 0x000c0000, 0x000c0010, 0x000c4000, 0x000c4010, -+ 0x00080100, 0x00080110, 0x00084100, 0x00084110, 0x000c0100, 0x000c0110, -+ 0x000c4100, 0x000c4110, 0x000a0000, 0x000a0010, 0x000a4000, 0x000a4010, -+ 0x000e0000, 0x000e0010, 0x000e4000, 0x000e4010, 0x000a0100, 0x000a0110, -+ 0x000a4100, 0x000a4110, 0x000e0100, 0x000e0110, 0x000e4100, 0x000e4110, -+ 0x00080001, 0x00080011, 0x00084001, 0x00084011, 0x000c0001, 0x000c0011, -+ 0x000c4001, 0x000c4011, 0x00080101, 0x00080111, 0x00084101, 0x00084111, -+ 0x000c0101, 0x000c0111, 0x000c4101, 0x000c4111, 0x000a0001, 0x000a0011, -+ 0x000a4001, 0x000a4011, 0x000e0001, 0x000e0011, 0x000e4001, 0x000e4011, -+ 0x000a0101, 0x000a0111, 0x000a4101, 0x000a4111, 0x000e0101, 0x000e0111, -+ 0x000e4101, 0x000e4111, -+ }, -+ { -+ 0x00000000, 0x00800000, 0x00000002, 0x00800002, 0x00000200, 0x00800200, -+ 0x00000202, 0x00800202, 0x00200000, 0x00a00000, 0x00200002, 0x00a00002, -+ 0x00200200, 0x00a00200, 0x00200202, 0x00a00202, 0x00001000, 0x00801000, -+ 0x00001002, 0x00801002, 0x00001200, 0x00801200, 0x00001202, 0x00801202, -+ 0x00201000, 0x00a01000, 0x00201002, 0x00a01002, 0x00201200, 0x00a01200, -+ 0x00201202, 0x00a01202, 0x00000000, 0x00800000, 0x00000002, 0x00800002, -+ 0x00000200, 0x00800200, 0x00000202, 0x00800202, 0x00200000, 0x00a00000, -+ 0x00200002, 0x00a00002, 0x00200200, 0x00a00200, 0x00200202, 0x00a00202, -+ 0x00001000, 0x00801000, 0x00001002, 0x00801002, 0x00001200, 0x00801200, -+ 0x00001202, 0x00801202, 0x00201000, 0x00a01000, 0x00201002, 0x00a01002, -+ 0x00201200, 0x00a01200, 0x00201202, 0x00a01202, 0x00000040, 0x00800040, -+ 0x00000042, 0x00800042, 0x00000240, 0x00800240, 0x00000242, 0x00800242, -+ 0x00200040, 0x00a00040, 0x00200042, 0x00a00042, 0x00200240, 0x00a00240, -+ 0x00200242, 0x00a00242, 0x00001040, 0x00801040, 0x00001042, 0x00801042, -+ 0x00001240, 0x00801240, 0x00001242, 0x00801242, 0x00201040, 0x00a01040, -+ 0x00201042, 0x00a01042, 0x00201240, 0x00a01240, 0x00201242, 0x00a01242, -+ 0x00000040, 0x00800040, 0x00000042, 0x00800042, 0x00000240, 0x00800240, -+ 0x00000242, 0x00800242, 0x00200040, 0x00a00040, 0x00200042, 0x00a00042, -+ 0x00200240, 0x00a00240, 0x00200242, 0x00a00242, 0x00001040, 0x00801040, -+ 0x00001042, 0x00801042, 0x00001240, 0x00801240, 0x00001242, 0x00801242, -+ 0x00201040, 0x00a01040, 0x00201042, 0x00a01042, 0x00201240, 0x00a01240, -+ 0x00201242, 0x00a01242, -+ }, -+ { -+ 0x00000000, 0x00002000, 0x00000004, 0x00002004, 0x00000400, 0x00002400, -+ 0x00000404, 0x00002404, 0x00000000, 0x00002000, 0x00000004, 0x00002004, -+ 0x00000400, 0x00002400, 0x00000404, 0x00002404, 0x00400000, 0x00402000, -+ 0x00400004, 0x00402004, 0x00400400, 0x00402400, 0x00400404, 0x00402404, -+ 0x00400000, 0x00402000, 0x00400004, 0x00402004, 0x00400400, 0x00402400, -+ 0x00400404, 0x00402404, 0x00000020, 0x00002020, 0x00000024, 0x00002024, -+ 0x00000420, 0x00002420, 0x00000424, 0x00002424, 0x00000020, 0x00002020, -+ 0x00000024, 0x00002024, 0x00000420, 0x00002420, 0x00000424, 0x00002424, -+ 0x00400020, 0x00402020, 0x00400024, 0x00402024, 0x00400420, 0x00402420, -+ 0x00400424, 0x00402424, 0x00400020, 0x00402020, 0x00400024, 0x00402024, -+ 0x00400420, 0x00402420, 0x00400424, 0x00402424, 0x00008000, 0x0000a000, -+ 0x00008004, 0x0000a004, 0x00008400, 0x0000a400, 0x00008404, 0x0000a404, -+ 0x00008000, 0x0000a000, 0x00008004, 0x0000a004, 0x00008400, 0x0000a400, -+ 0x00008404, 0x0000a404, 0x00408000, 0x0040a000, 0x00408004, 0x0040a004, -+ 0x00408400, 0x0040a400, 0x00408404, 0x0040a404, 0x00408000, 0x0040a000, -+ 0x00408004, 0x0040a004, 0x00408400, 0x0040a400, 0x00408404, 0x0040a404, -+ 0x00008020, 0x0000a020, 0x00008024, 0x0000a024, 0x00008420, 0x0000a420, -+ 0x00008424, 0x0000a424, 0x00008020, 0x0000a020, 0x00008024, 0x0000a024, -+ 0x00008420, 0x0000a420, 0x00008424, 0x0000a424, 0x00408020, 0x0040a020, -+ 0x00408024, 0x0040a024, 0x00408420, 0x0040a420, 0x00408424, 0x0040a424, -+ 0x00408020, 0x0040a020, 0x00408024, 0x0040a024, 0x00408420, 0x0040a420, -+ 0x00408424, 0x0040a424, -+ }, -+ { -+ 0x00000000, 0x00010000, 0x00000008, 0x00010008, 0x00000080, 0x00010080, -+ 0x00000088, 0x00010088, 0x00000000, 0x00010000, 0x00000008, 0x00010008, -+ 0x00000080, 0x00010080, 0x00000088, 0x00010088, 0x00100000, 0x00110000, -+ 0x00100008, 0x00110008, 0x00100080, 0x00110080, 0x00100088, 0x00110088, -+ 0x00100000, 0x00110000, 0x00100008, 0x00110008, 0x00100080, 0x00110080, -+ 0x00100088, 0x00110088, 0x00000800, 0x00010800, 0x00000808, 0x00010808, -+ 0x00000880, 0x00010880, 0x00000888, 0x00010888, 0x00000800, 0x00010800, -+ 0x00000808, 0x00010808, 0x00000880, 0x00010880, 0x00000888, 0x00010888, -+ 0x00100800, 0x00110800, 0x00100808, 0x00110808, 0x00100880, 0x00110880, -+ 0x00100888, 0x00110888, 0x00100800, 0x00110800, 0x00100808, 0x00110808, -+ 0x00100880, 0x00110880, 0x00100888, 0x00110888, 0x00000000, 0x00010000, -+ 0x00000008, 0x00010008, 0x00000080, 0x00010080, 0x00000088, 0x00010088, -+ 0x00000000, 0x00010000, 0x00000008, 0x00010008, 0x00000080, 0x00010080, -+ 0x00000088, 0x00010088, 0x00100000, 0x00110000, 0x00100008, 0x00110008, -+ 0x00100080, 0x00110080, 0x00100088, 0x00110088, 0x00100000, 0x00110000, -+ 0x00100008, 0x00110008, 0x00100080, 0x00110080, 0x00100088, 0x00110088, -+ 0x00000800, 0x00010800, 0x00000808, 0x00010808, 0x00000880, 0x00010880, -+ 0x00000888, 0x00010888, 0x00000800, 0x00010800, 0x00000808, 0x00010808, -+ 0x00000880, 0x00010880, 0x00000888, 0x00010888, 0x00100800, 0x00110800, -+ 0x00100808, 0x00110808, 0x00100880, 0x00110880, 0x00100888, 0x00110888, -+ 0x00100800, 0x00110800, 0x00100808, 0x00110808, 0x00100880, 0x00110880, -+ 0x00100888, 0x00110888, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+}; -+ -+const uint32_t comp_maskr[8][128] = { -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -+ 0x00000000, 0x00000000, -+ }, -+ { -+ 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00002000, 0x00002000, -+ 0x00002080, 0x00002080, 0x00000001, 0x00000001, 0x00000081, 0x00000081, -+ 0x00002001, 0x00002001, 0x00002081, 0x00002081, 0x00200000, 0x00200000, -+ 0x00200080, 0x00200080, 0x00202000, 0x00202000, 0x00202080, 0x00202080, -+ 0x00200001, 0x00200001, 0x00200081, 0x00200081, 0x00202001, 0x00202001, -+ 0x00202081, 0x00202081, 0x00020000, 0x00020000, 0x00020080, 0x00020080, -+ 0x00022000, 0x00022000, 0x00022080, 0x00022080, 0x00020001, 0x00020001, -+ 0x00020081, 0x00020081, 0x00022001, 0x00022001, 0x00022081, 0x00022081, -+ 0x00220000, 0x00220000, 0x00220080, 0x00220080, 0x00222000, 0x00222000, -+ 0x00222080, 0x00222080, 0x00220001, 0x00220001, 0x00220081, 0x00220081, -+ 0x00222001, 0x00222001, 0x00222081, 0x00222081, 0x00000002, 0x00000002, -+ 0x00000082, 0x00000082, 0x00002002, 0x00002002, 0x00002082, 0x00002082, -+ 0x00000003, 0x00000003, 0x00000083, 0x00000083, 0x00002003, 0x00002003, -+ 0x00002083, 0x00002083, 0x00200002, 0x00200002, 0x00200082, 0x00200082, -+ 0x00202002, 0x00202002, 0x00202082, 0x00202082, 0x00200003, 0x00200003, -+ 0x00200083, 0x00200083, 0x00202003, 0x00202003, 0x00202083, 0x00202083, -+ 0x00020002, 0x00020002, 0x00020082, 0x00020082, 0x00022002, 0x00022002, -+ 0x00022082, 0x00022082, 0x00020003, 0x00020003, 0x00020083, 0x00020083, -+ 0x00022003, 0x00022003, 0x00022083, 0x00022083, 0x00220002, 0x00220002, -+ 0x00220082, 0x00220082, 0x00222002, 0x00222002, 0x00222082, 0x00222082, -+ 0x00220003, 0x00220003, 0x00220083, 0x00220083, 0x00222003, 0x00222003, -+ 0x00222083, 0x00222083, -+ }, -+ { -+ 0x00000000, 0x00000010, 0x00800000, 0x00800010, 0x00010000, 0x00010010, -+ 0x00810000, 0x00810010, 0x00000200, 0x00000210, 0x00800200, 0x00800210, -+ 0x00010200, 0x00010210, 0x00810200, 0x00810210, 0x00000000, 0x00000010, -+ 0x00800000, 0x00800010, 0x00010000, 0x00010010, 0x00810000, 0x00810010, -+ 0x00000200, 0x00000210, 0x00800200, 0x00800210, 0x00010200, 0x00010210, -+ 0x00810200, 0x00810210, 0x00100000, 0x00100010, 0x00900000, 0x00900010, -+ 0x00110000, 0x00110010, 0x00910000, 0x00910010, 0x00100200, 0x00100210, -+ 0x00900200, 0x00900210, 0x00110200, 0x00110210, 0x00910200, 0x00910210, -+ 0x00100000, 0x00100010, 0x00900000, 0x00900010, 0x00110000, 0x00110010, -+ 0x00910000, 0x00910010, 0x00100200, 0x00100210, 0x00900200, 0x00900210, -+ 0x00110200, 0x00110210, 0x00910200, 0x00910210, 0x00000004, 0x00000014, -+ 0x00800004, 0x00800014, 0x00010004, 0x00010014, 0x00810004, 0x00810014, -+ 0x00000204, 0x00000214, 0x00800204, 0x00800214, 0x00010204, 0x00010214, -+ 0x00810204, 0x00810214, 0x00000004, 0x00000014, 0x00800004, 0x00800014, -+ 0x00010004, 0x00010014, 0x00810004, 0x00810014, 0x00000204, 0x00000214, -+ 0x00800204, 0x00800214, 0x00010204, 0x00010214, 0x00810204, 0x00810214, -+ 0x00100004, 0x00100014, 0x00900004, 0x00900014, 0x00110004, 0x00110014, -+ 0x00910004, 0x00910014, 0x00100204, 0x00100214, 0x00900204, 0x00900214, -+ 0x00110204, 0x00110214, 0x00910204, 0x00910214, 0x00100004, 0x00100014, -+ 0x00900004, 0x00900014, 0x00110004, 0x00110014, 0x00910004, 0x00910014, -+ 0x00100204, 0x00100214, 0x00900204, 0x00900214, 0x00110204, 0x00110214, -+ 0x00910204, 0x00910214, -+ }, -+ { -+ 0x00000000, 0x00000400, 0x00001000, 0x00001400, 0x00080000, 0x00080400, -+ 0x00081000, 0x00081400, 0x00000020, 0x00000420, 0x00001020, 0x00001420, -+ 0x00080020, 0x00080420, 0x00081020, 0x00081420, 0x00004000, 0x00004400, -+ 0x00005000, 0x00005400, 0x00084000, 0x00084400, 0x00085000, 0x00085400, -+ 0x00004020, 0x00004420, 0x00005020, 0x00005420, 0x00084020, 0x00084420, -+ 0x00085020, 0x00085420, 0x00000800, 0x00000c00, 0x00001800, 0x00001c00, -+ 0x00080800, 0x00080c00, 0x00081800, 0x00081c00, 0x00000820, 0x00000c20, -+ 0x00001820, 0x00001c20, 0x00080820, 0x00080c20, 0x00081820, 0x00081c20, -+ 0x00004800, 0x00004c00, 0x00005800, 0x00005c00, 0x00084800, 0x00084c00, -+ 0x00085800, 0x00085c00, 0x00004820, 0x00004c20, 0x00005820, 0x00005c20, -+ 0x00084820, 0x00084c20, 0x00085820, 0x00085c20, 0x00000000, 0x00000400, -+ 0x00001000, 0x00001400, 0x00080000, 0x00080400, 0x00081000, 0x00081400, -+ 0x00000020, 0x00000420, 0x00001020, 0x00001420, 0x00080020, 0x00080420, -+ 0x00081020, 0x00081420, 0x00004000, 0x00004400, 0x00005000, 0x00005400, -+ 0x00084000, 0x00084400, 0x00085000, 0x00085400, 0x00004020, 0x00004420, -+ 0x00005020, 0x00005420, 0x00084020, 0x00084420, 0x00085020, 0x00085420, -+ 0x00000800, 0x00000c00, 0x00001800, 0x00001c00, 0x00080800, 0x00080c00, -+ 0x00081800, 0x00081c00, 0x00000820, 0x00000c20, 0x00001820, 0x00001c20, -+ 0x00080820, 0x00080c20, 0x00081820, 0x00081c20, 0x00004800, 0x00004c00, -+ 0x00005800, 0x00005c00, 0x00084800, 0x00084c00, 0x00085800, 0x00085c00, -+ 0x00004820, 0x00004c20, 0x00005820, 0x00005c20, 0x00084820, 0x00084c20, -+ 0x00085820, 0x00085c20, -+ }, -+ { -+ 0x00000000, 0x00000100, 0x00040000, 0x00040100, 0x00000000, 0x00000100, -+ 0x00040000, 0x00040100, 0x00000040, 0x00000140, 0x00040040, 0x00040140, -+ 0x00000040, 0x00000140, 0x00040040, 0x00040140, 0x00400000, 0x00400100, -+ 0x00440000, 0x00440100, 0x00400000, 0x00400100, 0x00440000, 0x00440100, -+ 0x00400040, 0x00400140, 0x00440040, 0x00440140, 0x00400040, 0x00400140, -+ 0x00440040, 0x00440140, 0x00008000, 0x00008100, 0x00048000, 0x00048100, -+ 0x00008000, 0x00008100, 0x00048000, 0x00048100, 0x00008040, 0x00008140, -+ 0x00048040, 0x00048140, 0x00008040, 0x00008140, 0x00048040, 0x00048140, -+ 0x00408000, 0x00408100, 0x00448000, 0x00448100, 0x00408000, 0x00408100, -+ 0x00448000, 0x00448100, 0x00408040, 0x00408140, 0x00448040, 0x00448140, -+ 0x00408040, 0x00408140, 0x00448040, 0x00448140, 0x00000008, 0x00000108, -+ 0x00040008, 0x00040108, 0x00000008, 0x00000108, 0x00040008, 0x00040108, -+ 0x00000048, 0x00000148, 0x00040048, 0x00040148, 0x00000048, 0x00000148, -+ 0x00040048, 0x00040148, 0x00400008, 0x00400108, 0x00440008, 0x00440108, -+ 0x00400008, 0x00400108, 0x00440008, 0x00440108, 0x00400048, 0x00400148, -+ 0x00440048, 0x00440148, 0x00400048, 0x00400148, 0x00440048, 0x00440148, -+ 0x00008008, 0x00008108, 0x00048008, 0x00048108, 0x00008008, 0x00008108, -+ 0x00048008, 0x00048108, 0x00008048, 0x00008148, 0x00048048, 0x00048148, -+ 0x00008048, 0x00008148, 0x00048048, 0x00048148, 0x00408008, 0x00408108, -+ 0x00448008, 0x00448108, 0x00408008, 0x00408108, 0x00448008, 0x00448108, -+ 0x00408048, 0x00408148, 0x00448048, 0x00448148, 0x00408048, 0x00408148, -+ 0x00448048, 0x00448148, -+ }, -+}; -+ -+const uint32_t psbox[4][256] = { -+ { -+ 0x00000000, 0x00004000, 0x40000000, 0x40004000, 0x00000010, 0x00004010, -+ 0x40000010, 0x40004010, 0x00080000, 0x00084000, 0x40080000, 0x40084000, -+ 0x00080010, 0x00084010, 0x40080010, 0x40084010, 0x00000002, 0x00004002, -+ 0x40000002, 0x40004002, 0x00000012, 0x00004012, 0x40000012, 0x40004012, -+ 0x00080002, 0x00084002, 0x40080002, 0x40084002, 0x00080012, 0x00084012, -+ 0x40080012, 0x40084012, 0x00000200, 0x00004200, 0x40000200, 0x40004200, -+ 0x00000210, 0x00004210, 0x40000210, 0x40004210, 0x00080200, 0x00084200, -+ 0x40080200, 0x40084200, 0x00080210, 0x00084210, 0x40080210, 0x40084210, -+ 0x00000202, 0x00004202, 0x40000202, 0x40004202, 0x00000212, 0x00004212, -+ 0x40000212, 0x40004212, 0x00080202, 0x00084202, 0x40080202, 0x40084202, -+ 0x00080212, 0x00084212, 0x40080212, 0x40084212, 0x00008000, 0x0000c000, -+ 0x40008000, 0x4000c000, 0x00008010, 0x0000c010, 0x40008010, 0x4000c010, -+ 0x00088000, 0x0008c000, 0x40088000, 0x4008c000, 0x00088010, 0x0008c010, -+ 0x40088010, 0x4008c010, 0x00008002, 0x0000c002, 0x40008002, 0x4000c002, -+ 0x00008012, 0x0000c012, 0x40008012, 0x4000c012, 0x00088002, 0x0008c002, -+ 0x40088002, 0x4008c002, 0x00088012, 0x0008c012, 0x40088012, 0x4008c012, -+ 0x00008200, 0x0000c200, 0x40008200, 0x4000c200, 0x00008210, 0x0000c210, -+ 0x40008210, 0x4000c210, 0x00088200, 0x0008c200, 0x40088200, 0x4008c200, -+ 0x00088210, 0x0008c210, 0x40088210, 0x4008c210, 0x00008202, 0x0000c202, -+ 0x40008202, 0x4000c202, 0x00008212, 0x0000c212, 0x40008212, 0x4000c212, -+ 0x00088202, 0x0008c202, 0x40088202, 0x4008c202, 0x00088212, 0x0008c212, -+ 0x40088212, 0x4008c212, 0x00800000, 0x00804000, 0x40800000, 0x40804000, -+ 0x00800010, 0x00804010, 0x40800010, 0x40804010, 0x00880000, 0x00884000, -+ 0x40880000, 0x40884000, 0x00880010, 0x00884010, 0x40880010, 0x40884010, -+ 0x00800002, 0x00804002, 0x40800002, 0x40804002, 0x00800012, 0x00804012, -+ 0x40800012, 0x40804012, 0x00880002, 0x00884002, 0x40880002, 0x40884002, -+ 0x00880012, 0x00884012, 0x40880012, 0x40884012, 0x00800200, 0x00804200, -+ 0x40800200, 0x40804200, 0x00800210, 0x00804210, 0x40800210, 0x40804210, -+ 0x00880200, 0x00884200, 0x40880200, 0x40884200, 0x00880210, 0x00884210, -+ 0x40880210, 0x40884210, 0x00800202, 0x00804202, 0x40800202, 0x40804202, -+ 0x00800212, 0x00804212, 0x40800212, 0x40804212, 0x00880202, 0x00884202, -+ 0x40880202, 0x40884202, 0x00880212, 0x00884212, 0x40880212, 0x40884212, -+ 0x00808000, 0x0080c000, 0x40808000, 0x4080c000, 0x00808010, 0x0080c010, -+ 0x40808010, 0x4080c010, 0x00888000, 0x0088c000, 0x40888000, 0x4088c000, -+ 0x00888010, 0x0088c010, 0x40888010, 0x4088c010, 0x00808002, 0x0080c002, -+ 0x40808002, 0x4080c002, 0x00808012, 0x0080c012, 0x40808012, 0x4080c012, -+ 0x00888002, 0x0088c002, 0x40888002, 0x4088c002, 0x00888012, 0x0088c012, -+ 0x40888012, 0x4088c012, 0x00808200, 0x0080c200, 0x40808200, 0x4080c200, -+ 0x00808210, 0x0080c210, 0x40808210, 0x4080c210, 0x00888200, 0x0088c200, -+ 0x40888200, 0x4088c200, 0x00888210, 0x0088c210, 0x40888210, 0x4088c210, -+ 0x00808202, 0x0080c202, 0x40808202, 0x4080c202, 0x00808212, 0x0080c212, -+ 0x40808212, 0x4080c212, 0x00888202, 0x0088c202, 0x40888202, 0x4088c202, -+ 0x00888212, 0x0088c212, 0x40888212, 0x4088c212, -+ }, -+ { -+ 0x00000000, 0x80000000, 0x00400000, 0x80400000, 0x00001000, 0x80001000, -+ 0x00401000, 0x80401000, 0x00000040, 0x80000040, 0x00400040, 0x80400040, -+ 0x00001040, 0x80001040, 0x00401040, 0x80401040, 0x04000000, 0x84000000, -+ 0x04400000, 0x84400000, 0x04001000, 0x84001000, 0x04401000, 0x84401000, -+ 0x04000040, 0x84000040, 0x04400040, 0x84400040, 0x04001040, 0x84001040, -+ 0x04401040, 0x84401040, 0x00000004, 0x80000004, 0x00400004, 0x80400004, -+ 0x00001004, 0x80001004, 0x00401004, 0x80401004, 0x00000044, 0x80000044, -+ 0x00400044, 0x80400044, 0x00001044, 0x80001044, 0x00401044, 0x80401044, -+ 0x04000004, 0x84000004, 0x04400004, 0x84400004, 0x04001004, 0x84001004, -+ 0x04401004, 0x84401004, 0x04000044, 0x84000044, 0x04400044, 0x84400044, -+ 0x04001044, 0x84001044, 0x04401044, 0x84401044, 0x00010000, 0x80010000, -+ 0x00410000, 0x80410000, 0x00011000, 0x80011000, 0x00411000, 0x80411000, -+ 0x00010040, 0x80010040, 0x00410040, 0x80410040, 0x00011040, 0x80011040, -+ 0x00411040, 0x80411040, 0x04010000, 0x84010000, 0x04410000, 0x84410000, -+ 0x04011000, 0x84011000, 0x04411000, 0x84411000, 0x04010040, 0x84010040, -+ 0x04410040, 0x84410040, 0x04011040, 0x84011040, 0x04411040, 0x84411040, -+ 0x00010004, 0x80010004, 0x00410004, 0x80410004, 0x00011004, 0x80011004, -+ 0x00411004, 0x80411004, 0x00010044, 0x80010044, 0x00410044, 0x80410044, -+ 0x00011044, 0x80011044, 0x00411044, 0x80411044, 0x04010004, 0x84010004, -+ 0x04410004, 0x84410004, 0x04011004, 0x84011004, 0x04411004, 0x84411004, -+ 0x04010044, 0x84010044, 0x04410044, 0x84410044, 0x04011044, 0x84011044, -+ 0x04411044, 0x84411044, 0x00000100, 0x80000100, 0x00400100, 0x80400100, -+ 0x00001100, 0x80001100, 0x00401100, 0x80401100, 0x00000140, 0x80000140, -+ 0x00400140, 0x80400140, 0x00001140, 0x80001140, 0x00401140, 0x80401140, -+ 0x04000100, 0x84000100, 0x04400100, 0x84400100, 0x04001100, 0x84001100, -+ 0x04401100, 0x84401100, 0x04000140, 0x84000140, 0x04400140, 0x84400140, -+ 0x04001140, 0x84001140, 0x04401140, 0x84401140, 0x00000104, 0x80000104, -+ 0x00400104, 0x80400104, 0x00001104, 0x80001104, 0x00401104, 0x80401104, -+ 0x00000144, 0x80000144, 0x00400144, 0x80400144, 0x00001144, 0x80001144, -+ 0x00401144, 0x80401144, 0x04000104, 0x84000104, 0x04400104, 0x84400104, -+ 0x04001104, 0x84001104, 0x04401104, 0x84401104, 0x04000144, 0x84000144, -+ 0x04400144, 0x84400144, 0x04001144, 0x84001144, 0x04401144, 0x84401144, -+ 0x00010100, 0x80010100, 0x00410100, 0x80410100, 0x00011100, 0x80011100, -+ 0x00411100, 0x80411100, 0x00010140, 0x80010140, 0x00410140, 0x80410140, -+ 0x00011140, 0x80011140, 0x00411140, 0x80411140, 0x04010100, 0x84010100, -+ 0x04410100, 0x84410100, 0x04011100, 0x84011100, 0x04411100, 0x84411100, -+ 0x04010140, 0x84010140, 0x04410140, 0x84410140, 0x04011140, 0x84011140, -+ 0x04411140, 0x84411140, 0x00010104, 0x80010104, 0x00410104, 0x80410104, -+ 0x00011104, 0x80011104, 0x00411104, 0x80411104, 0x00010144, 0x80010144, -+ 0x00410144, 0x80410144, 0x00011144, 0x80011144, 0x00411144, 0x80411144, -+ 0x04010104, 0x84010104, 0x04410104, 0x84410104, 0x04011104, 0x84011104, -+ 0x04411104, 0x84411104, 0x04010144, 0x84010144, 0x04410144, 0x84410144, -+ 0x04011144, 0x84011144, 0x04411144, 0x84411144, -+ }, -+ { -+ 0x00000000, 0x00002000, 0x00200000, 0x00202000, 0x00000008, 0x00002008, -+ 0x00200008, 0x00202008, 0x10000000, 0x10002000, 0x10200000, 0x10202000, -+ 0x10000008, 0x10002008, 0x10200008, 0x10202008, 0x20000000, 0x20002000, -+ 0x20200000, 0x20202000, 0x20000008, 0x20002008, 0x20200008, 0x20202008, -+ 0x30000000, 0x30002000, 0x30200000, 0x30202000, 0x30000008, 0x30002008, -+ 0x30200008, 0x30202008, 0x00000080, 0x00002080, 0x00200080, 0x00202080, -+ 0x00000088, 0x00002088, 0x00200088, 0x00202088, 0x10000080, 0x10002080, -+ 0x10200080, 0x10202080, 0x10000088, 0x10002088, 0x10200088, 0x10202088, -+ 0x20000080, 0x20002080, 0x20200080, 0x20202080, 0x20000088, 0x20002088, -+ 0x20200088, 0x20202088, 0x30000080, 0x30002080, 0x30200080, 0x30202080, -+ 0x30000088, 0x30002088, 0x30200088, 0x30202088, 0x00040000, 0x00042000, -+ 0x00240000, 0x00242000, 0x00040008, 0x00042008, 0x00240008, 0x00242008, -+ 0x10040000, 0x10042000, 0x10240000, 0x10242000, 0x10040008, 0x10042008, -+ 0x10240008, 0x10242008, 0x20040000, 0x20042000, 0x20240000, 0x20242000, -+ 0x20040008, 0x20042008, 0x20240008, 0x20242008, 0x30040000, 0x30042000, -+ 0x30240000, 0x30242000, 0x30040008, 0x30042008, 0x30240008, 0x30242008, -+ 0x00040080, 0x00042080, 0x00240080, 0x00242080, 0x00040088, 0x00042088, -+ 0x00240088, 0x00242088, 0x10040080, 0x10042080, 0x10240080, 0x10242080, -+ 0x10040088, 0x10042088, 0x10240088, 0x10242088, 0x20040080, 0x20042080, -+ 0x20240080, 0x20242080, 0x20040088, 0x20042088, 0x20240088, 0x20242088, -+ 0x30040080, 0x30042080, 0x30240080, 0x30242080, 0x30040088, 0x30042088, -+ 0x30240088, 0x30242088, 0x01000000, 0x01002000, 0x01200000, 0x01202000, -+ 0x01000008, 0x01002008, 0x01200008, 0x01202008, 0x11000000, 0x11002000, -+ 0x11200000, 0x11202000, 0x11000008, 0x11002008, 0x11200008, 0x11202008, -+ 0x21000000, 0x21002000, 0x21200000, 0x21202000, 0x21000008, 0x21002008, -+ 0x21200008, 0x21202008, 0x31000000, 0x31002000, 0x31200000, 0x31202000, -+ 0x31000008, 0x31002008, 0x31200008, 0x31202008, 0x01000080, 0x01002080, -+ 0x01200080, 0x01202080, 0x01000088, 0x01002088, 0x01200088, 0x01202088, -+ 0x11000080, 0x11002080, 0x11200080, 0x11202080, 0x11000088, 0x11002088, -+ 0x11200088, 0x11202088, 0x21000080, 0x21002080, 0x21200080, 0x21202080, -+ 0x21000088, 0x21002088, 0x21200088, 0x21202088, 0x31000080, 0x31002080, -+ 0x31200080, 0x31202080, 0x31000088, 0x31002088, 0x31200088, 0x31202088, -+ 0x01040000, 0x01042000, 0x01240000, 0x01242000, 0x01040008, 0x01042008, -+ 0x01240008, 0x01242008, 0x11040000, 0x11042000, 0x11240000, 0x11242000, -+ 0x11040008, 0x11042008, 0x11240008, 0x11242008, 0x21040000, 0x21042000, -+ 0x21240000, 0x21242000, 0x21040008, 0x21042008, 0x21240008, 0x21242008, -+ 0x31040000, 0x31042000, 0x31240000, 0x31242000, 0x31040008, 0x31042008, -+ 0x31240008, 0x31242008, 0x01040080, 0x01042080, 0x01240080, 0x01242080, -+ 0x01040088, 0x01042088, 0x01240088, 0x01242088, 0x11040080, 0x11042080, -+ 0x11240080, 0x11242080, 0x11040088, 0x11042088, 0x11240088, 0x11242088, -+ 0x21040080, 0x21042080, 0x21240080, 0x21242080, 0x21040088, 0x21042088, -+ 0x21240088, 0x21242088, 0x31040080, 0x31042080, 0x31240080, 0x31242080, -+ 0x31040088, 0x31042088, 0x31240088, 0x31242088, -+ }, -+ { -+ 0x00000000, 0x00000800, 0x00020000, 0x00020800, 0x00000020, 0x00000820, -+ 0x00020020, 0x00020820, 0x08000000, 0x08000800, 0x08020000, 0x08020800, -+ 0x08000020, 0x08000820, 0x08020020, 0x08020820, 0x02000000, 0x02000800, -+ 0x02020000, 0x02020800, 0x02000020, 0x02000820, 0x02020020, 0x02020820, -+ 0x0a000000, 0x0a000800, 0x0a020000, 0x0a020800, 0x0a000020, 0x0a000820, -+ 0x0a020020, 0x0a020820, 0x00000400, 0x00000c00, 0x00020400, 0x00020c00, -+ 0x00000420, 0x00000c20, 0x00020420, 0x00020c20, 0x08000400, 0x08000c00, -+ 0x08020400, 0x08020c00, 0x08000420, 0x08000c20, 0x08020420, 0x08020c20, -+ 0x02000400, 0x02000c00, 0x02020400, 0x02020c00, 0x02000420, 0x02000c20, -+ 0x02020420, 0x02020c20, 0x0a000400, 0x0a000c00, 0x0a020400, 0x0a020c00, -+ 0x0a000420, 0x0a000c20, 0x0a020420, 0x0a020c20, 0x00100000, 0x00100800, -+ 0x00120000, 0x00120800, 0x00100020, 0x00100820, 0x00120020, 0x00120820, -+ 0x08100000, 0x08100800, 0x08120000, 0x08120800, 0x08100020, 0x08100820, -+ 0x08120020, 0x08120820, 0x02100000, 0x02100800, 0x02120000, 0x02120800, -+ 0x02100020, 0x02100820, 0x02120020, 0x02120820, 0x0a100000, 0x0a100800, -+ 0x0a120000, 0x0a120800, 0x0a100020, 0x0a100820, 0x0a120020, 0x0a120820, -+ 0x00100400, 0x00100c00, 0x00120400, 0x00120c00, 0x00100420, 0x00100c20, -+ 0x00120420, 0x00120c20, 0x08100400, 0x08100c00, 0x08120400, 0x08120c00, -+ 0x08100420, 0x08100c20, 0x08120420, 0x08120c20, 0x02100400, 0x02100c00, -+ 0x02120400, 0x02120c00, 0x02100420, 0x02100c20, 0x02120420, 0x02120c20, -+ 0x0a100400, 0x0a100c00, 0x0a120400, 0x0a120c00, 0x0a100420, 0x0a100c20, -+ 0x0a120420, 0x0a120c20, 0x00000001, 0x00000801, 0x00020001, 0x00020801, -+ 0x00000021, 0x00000821, 0x00020021, 0x00020821, 0x08000001, 0x08000801, -+ 0x08020001, 0x08020801, 0x08000021, 0x08000821, 0x08020021, 0x08020821, -+ 0x02000001, 0x02000801, 0x02020001, 0x02020801, 0x02000021, 0x02000821, -+ 0x02020021, 0x02020821, 0x0a000001, 0x0a000801, 0x0a020001, 0x0a020801, -+ 0x0a000021, 0x0a000821, 0x0a020021, 0x0a020821, 0x00000401, 0x00000c01, -+ 0x00020401, 0x00020c01, 0x00000421, 0x00000c21, 0x00020421, 0x00020c21, -+ 0x08000401, 0x08000c01, 0x08020401, 0x08020c01, 0x08000421, 0x08000c21, -+ 0x08020421, 0x08020c21, 0x02000401, 0x02000c01, 0x02020401, 0x02020c01, -+ 0x02000421, 0x02000c21, 0x02020421, 0x02020c21, 0x0a000401, 0x0a000c01, -+ 0x0a020401, 0x0a020c01, 0x0a000421, 0x0a000c21, 0x0a020421, 0x0a020c21, -+ 0x00100001, 0x00100801, 0x00120001, 0x00120801, 0x00100021, 0x00100821, -+ 0x00120021, 0x00120821, 0x08100001, 0x08100801, 0x08120001, 0x08120801, -+ 0x08100021, 0x08100821, 0x08120021, 0x08120821, 0x02100001, 0x02100801, -+ 0x02120001, 0x02120801, 0x02100021, 0x02100821, 0x02120021, 0x02120821, -+ 0x0a100001, 0x0a100801, 0x0a120001, 0x0a120801, 0x0a100021, 0x0a100821, -+ 0x0a120021, 0x0a120821, 0x00100401, 0x00100c01, 0x00120401, 0x00120c01, -+ 0x00100421, 0x00100c21, 0x00120421, 0x00120c21, 0x08100401, 0x08100c01, -+ 0x08120401, 0x08120c01, 0x08100421, 0x08100c21, 0x08120421, 0x08120c21, -+ 0x02100401, 0x02100c01, 0x02120401, 0x02120c01, 0x02100421, 0x02100c21, -+ 0x02120421, 0x02120c21, 0x0a100401, 0x0a100c01, 0x0a120401, 0x0a120c01, -+ 0x0a100421, 0x0a100c21, 0x0a120421, 0x0a120c21, -+ }, -+}; -diff --git a/configure.ac b/configure.ac -index 9846e3f..f843b51 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -24,7 +24,6 @@ AH_BOTTOM( - # Checks for programs. - AC_CANONICAL_HOST - AC_PROG_CC --AX_PROG_CC_FOR_BUILD - - # Dependencies - PKG_PROG_PKG_CONFIG -diff --git a/gen-des-tables.c b/gen-des-tables.c -index cf2b76f..ee18cd4 100644 ---- a/gen-des-tables.c -+++ b/gen-des-tables.c -@@ -40,6 +40,12 @@ - * by David Burren . - */ - -+/* -+ * This program can regenerate the tables in alg-des-tables.c. -+ * It is preserved as documentation, but it should no longer be -+ * necessary to run it. -+ */ -+ - #include "crypt-port.h" - - #include -@@ -341,11 +347,6 @@ main(void) - { - des_init(); - -- puts("/* Generated by gen-des-tables. DO NOT EDIT. */\n" -- "\n" -- "#include \"crypt-port.h\"\n" -- "#include \"alg-des.h\""); -- - write_table_u8(4, 4096, &m_sbox_[0][0], "m_sbox"); - - write_table_u32(8, 256, &ip_maskl_[0][0], "ip_maskl"); -diff --git a/m4/ax_prog_cc_for_build.m4 b/m4/ax_prog_cc_for_build.m4 -deleted file mode 100644 -index ac6043a..0000000 ---- a/m4/ax_prog_cc_for_build.m4 -+++ /dev/null -@@ -1,158 +0,0 @@ --# =========================================================================== --# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html --# =========================================================================== --# --# SYNOPSIS --# --# AX_PROG_CC_FOR_BUILD --# --# DESCRIPTION --# --# This macro searches for a C compiler that generates native executables, --# that is a C compiler that surely is not a cross-compiler. This can be --# useful if you have to generate source code at compile-time like for --# example GCC does. --# --# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything --# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). --# The value of these variables can be overridden by the user by specifying --# a compiler with an environment variable (like you do for standard CC). --# --# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object --# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if --# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are --# substituted in the Makefile. --# --# LICENSE --# --# Copyright (c) 2008 Paolo Bonzini --# --# Copying and distribution of this file, with or without modification, are --# permitted in any medium without royalty provided the copyright notice --# and this notice are preserved. This file is offered as-is, without any --# warranty. -- --#serial 9 -- --AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) --AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl --AC_REQUIRE([AC_PROG_CC])dnl --AC_REQUIRE([AC_PROG_CPP])dnl --AC_REQUIRE([AC_EXEEXT])dnl --AC_REQUIRE([AC_CANONICAL_HOST])dnl -- --dnl Use the standard macros, but make them use other variable names --dnl --pushdef([_AC_LANG_ABBREV], [build_c])dnl --pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl --pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl --pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl --pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl --pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl --pushdef([ac_cv_prog_cc_stdc], ac_cv_build_prog_cc_stdc)dnl --pushdef([ac_cv_prog_cc_c11], ac_cv_build_prog_cc_c11)dnl --pushdef([ac_cv_prog_cc_c99], ac_cv_build_prog_cc_c99)dnl --pushdef([ac_prog_cc_stdc], ac_build_prog_cc_stdc)dnl --pushdef([am_cv_CC_dependencies_compiler_type], -- am_cv_build_CC_depencies_compiler_type)dnl --pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl --pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl --pushdef([ac_cv_objext], ac_cv_build_objext)dnl --pushdef([ac_exeext], ac_build_exeext)dnl --pushdef([ac_objext], ac_build_objext)dnl --pushdef([CC], CC_FOR_BUILD)dnl --pushdef([CPP], CPP_FOR_BUILD)dnl --pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl --pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl --pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl --pushdef([host], build)dnl --pushdef([host_alias], build_alias)dnl --pushdef([host_cpu], build_cpu)dnl --pushdef([host_vendor], build_vendor)dnl --pushdef([host_os], build_os)dnl --pushdef([ac_cv_host], ac_cv_build)dnl --pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl --pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl --pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl --pushdef([ac_cv_host_os], ac_cv_build_os)dnl --pushdef([ac_cpp], ac_build_cpp)dnl --pushdef([ac_compile], ac_build_compile)dnl --pushdef([ac_link], ac_build_link)dnl -- --dnl Shim the shell functions used by AC_COMPILE_IFELSE etc. --AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_cpp], -- [# Forward ac_fn_build_c_* to ac_fn_c_*.], -- [ac_fn_c_try_cpp "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_compile],,[ac_fn_c_try_compile "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_link],,[ac_fn_c_try_link "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_try_run],,[ac_fn_c_try_run "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_decl],,[ac_fn_c_check_decl "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_func],,[ac_fn_c_check_func "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_header_mongrel],,[ac_fn_c_check_header_mongrel "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_header_compile],,[ac_fn_c_check_header_compile "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_header_preproc],,[ac_fn_c_check_header_preproc "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_member],,[ac_fn_c_check_member "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_check_type],,[ac_fn_c_check_type "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_compute_int],,[ac_fn_c_compute_int "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_find_intX_t],,[ac_fn_c_find_intX_t "$][@"]) --AC_REQUIRE_SHELL_FN([ac_fn_build_c_find_uintX_t],,[ac_fn_c_find_uintX_t "$][@"]) -- --save_cross_compiling=$cross_compiling --save_ac_tool_prefix=$ac_tool_prefix --cross_compiling=no --ac_tool_prefix= -- --AC_PROG_CC --AC_PROG_CPP --AC_EXEEXT -- --ac_tool_prefix=$save_ac_tool_prefix --cross_compiling=$save_cross_compiling -- --dnl Restore the old definitions --dnl --popdef([ac_link])dnl --popdef([ac_compile])dnl --popdef([ac_cpp])dnl --popdef([ac_cv_host_os])dnl --popdef([ac_cv_host_vendor])dnl --popdef([ac_cv_host_cpu])dnl --popdef([ac_cv_host_alias])dnl --popdef([ac_cv_host])dnl --popdef([host_os])dnl --popdef([host_vendor])dnl --popdef([host_cpu])dnl --popdef([host_alias])dnl --popdef([host])dnl --popdef([LDFLAGS])dnl --popdef([CPPFLAGS])dnl --popdef([CFLAGS])dnl --popdef([CPP])dnl --popdef([CC])dnl --popdef([ac_objext])dnl --popdef([ac_exeext])dnl --popdef([ac_cv_objext])dnl --popdef([ac_cv_exeext])dnl --popdef([am_cv_prog_cc_c_o])dnl --popdef([am_cv_CC_dependencies_compiler_type])dnl --popdef([ac_prog_cc_stdc])dnl --popdef([ac_cv_prog_cc_c99])dnl --popdef([ac_cv_prog_cc_c11])dnl --popdef([ac_cv_prog_cc_stdc])dnl --popdef([ac_cv_prog_cc_g])dnl --popdef([ac_cv_prog_cc_cross])dnl --popdef([ac_cv_prog_cc_works])dnl --popdef([ac_cv_prog_gcc])dnl --popdef([ac_cv_prog_CPP])dnl --popdef([_AC_LANG_ABBREV])dnl -- --dnl Finally, set Makefile variables --dnl --BUILD_EXEEXT=$ac_build_exeext --BUILD_OBJEXT=$ac_build_objext --AC_SUBST(BUILD_EXEEXT)dnl --AC_SUBST(BUILD_OBJEXT)dnl --AC_SUBST([CFLAGS_FOR_BUILD])dnl --AC_SUBST([CPPFLAGS_FOR_BUILD])dnl --AC_SUBST([LDFLAGS_FOR_BUILD])dnl --]) - -From ed4be6afa7b34fe0d827cc3f7f9608de0d9325cd Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Wed, 4 Jul 2018 21:42:36 -0400 -Subject: [PATCH 15/41] Make it possible to disable individual hashes at - configure time. - -The table of supported hash algorithms now lives in hashes.lst. -The configure script accepts an option --enable-hashes which takes a -comma-separated list of hash algorithms to include. We generate a -header that defines INCLUDE_ macros for each hash that is enabled, -and all of the code is conditionalized appropriately. - -The default is --enable-hashes=all. --enable-hashes=strong is the -equivalent of the old --disable-weak-hashes. You could even do ---enable-hashes=bcrypt,des to get a binary-compatible libcrypt.so.1 -that still supports almost nothing other than bcrypt. ---- - .gitignore | 1 + - Makefile.am | 63 +++++++++---------- - README.md | 12 ++-- - alg-des-tables.c | 4 ++ - alg-des.c | 5 ++ - alg-hmac-sha1.c | 4 ++ - alg-md4.c | 4 ++ - alg-md5.c | 3 + - alg-sha1.c | 3 + - alg-sha256.c | 3 + - alg-sha512.c | 3 + - configure.ac | 59 ++++++++--------- - crypt-bcrypt.c | 4 ++ - crypt-des.c | 61 ++++++++++-------- - crypt-gensalt.c | 4 ++ - crypt-md5.c | 3 + - crypt-nthash.c | 4 ++ - crypt-pbkdf1-sha1.c | 4 ++ - crypt-port.h | 74 +++++++++++----------- - crypt-private.h | 82 ------------------------ - crypt-sha256.c | 3 + - crypt-sha512.c | 3 + - crypt-sunmd5.c | 5 ++ - crypt.c | 94 +++++++++------------------- - gen-hashes.awk | 160 +++++++++++++++++++++++++++++++++++++++++++++++ - hashes.lst | 40 ++++++++++++ - sel-hashes.awk | 89 ++++++++++++++++++++++++++ - test-alg-des.c | 12 ++++ - test-alg-hmac-sha1.c | 12 ++++ - test-alg-md4.c | 12 ++++ - test-alg-md5.c | 12 ++++ - test-alg-sha1.c | 12 ++++ - test-alg-sha256.c | 12 ++++ - test-alg-sha512.c | 12 ++++ - test-crypt-badsalt.c | 2 + - test-crypt-bcrypt.c | 12 ++++ - test-crypt-des.c | 18 +++++- - test-crypt-md5.c | 12 ++++ - test-crypt-nthash.c | 12 ++++ - test-crypt-pbkdf1-sha1.c | 12 ++++ - test-crypt-sha256.c | 12 ++++ - test-crypt-sha512.c | 12 ++++ - test-crypt-sunmd5.c | 12 ++++ - test-gensalt.c | 61 +++++++++++++----- - 44 files changed, 745 insertions(+), 298 deletions(-) - create mode 100644 gen-hashes.awk - create mode 100644 hashes.lst - create mode 100644 sel-hashes.awk - -diff --git a/.gitignore b/.gitignore -index 5e998dd..9f443bd 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -43,6 +43,7 @@ - *.so - *.trs - /crypt.h -+/crypt-hashes.h - /crypt-symbol-vers.h - /libcrypt.map - /test-alg-des -diff --git a/Makefile.am b/Makefile.am -index 71fbd62..040d719 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -12,12 +12,14 @@ AM_CFLAGS = $(WARN_CFLAGS) - EXTRA_DIST = \ - LICENSING THANKS \ - libcrypt.map.in libcrypt.minver \ -- gen-map.awk gen-vers.awk gen-crypt-h.awk -+ gen-map.awk gen-vers.awk gen-crypt-h.awk \ -+ gen-hashes.awk sel-hashes.awk hashes.lst - - notrans_dist_man3_MANS = crypt_rn.3 crypt_gensalt.3 - notrans_dist_man5_MANS = crypt.5 - - nodist_include_HEADERS = crypt.h -+nodist_noinst_HEADERS = crypt-hashes.h - noinst_HEADERS = \ - alg-des.h alg-hmac-sha1.h alg-md4.h alg-md5.h \ - alg-sha1.h alg-sha256.h alg-sha512.h byteorder.h \ -@@ -26,9 +28,12 @@ noinst_HEADERS = \ - - lib_LTLIBRARIES = libcrypt.la - libcrypt_la_SOURCES = \ -- crypt.c crypt-static.c crypt-gensalt.c crypt-gensalt-static.c \ -- crypt-bcrypt.c crypt-sha512.c crypt-sha256.c \ -- alg-sha512.c alg-sha256.c randombytes.c -+ alg-des.c alg-des-tables.c alg-hmac-sha1.c alg-md4.c alg-md5.c \ -+ alg-sha1.c alg-sha256.c alg-sha512.c \ -+ crypt.c crypt-bcrypt.c crypt-des.c crypt-gensalt-static.c \ -+ crypt-gensalt.c crypt-md5.c crypt-nthash.c crypt-pbkdf1-sha1.c \ -+ crypt-sha256.c crypt-sha512.c crypt-static.c crypt-sunmd5.c \ -+ randombytes.c - - pkgconfig_DATA = libxcrypt.pc - -@@ -49,6 +54,7 @@ CONFIG_STATUS_DEPENDENCIES = libcrypt.minver - EXTRA_libcrypt_la_DEPENDENCIES = libcrypt.map - CLEANFILES = libcrypt.map libcrypt.map.T \ - crypt-symbol-vers.h crypt-symbol-vers.h.T \ -+ crypt-hashes.h crypt-hashes.h.T \ - crypt.h crypt.h.T - - libcrypt.map: libcrypt.map.in gen-map.awk Makefile -@@ -70,6 +76,12 @@ crypt.h: crypt-base.h gen-crypt-h.awk config.h - > crypt.h.T - $(AM_V_at)mv -f crypt.h.T crypt.h - -+crypt-hashes.h: hashes.lst gen-hashes.awk Makefile -+ $(AM_V_GEN)LC_ALL=C $(AWK) -f $(srcdir)/gen-hashes.awk \ -+ -v ENABLED_HASHES=$(hashes_enabled) \ -+ $(srcdir)/hashes.lst > crypt-hashes.h.T -+ $(AM_V_at)mv -f crypt-hashes.h.T crypt-hashes.h -+ - # When we are being binary compatible, also install symbolic links to - # mimic SUSE's libowcrypt; any program that uses -lowcrypt in its - # build, or already has a NEEDED entry for libowcrypt.so.1, will be -@@ -108,30 +120,13 @@ endif - endif - - check_PROGRAMS = \ -- test-alg-sha256 test-alg-sha512 \ -- test-crypt-sha256 test-crypt-sha512 test-crypt-bcrypt \ -- test-crypt-nonnull test-byteorder test-gensalt -- --if ENABLE_WEAK_HASHES --libcrypt_la_SOURCES += \ -- crypt-des.c crypt-md5.c alg-des.c alg-des-tables.c alg-md5.c -- --if ENABLE_WEAK_NON_GLIBC_HASHES --libcrypt_la_SOURCES += \ -- crypt-nthash.c crypt-pbkdf1-sha1.c crypt-sunmd5.c \ -- alg-hmac-sha1.c alg-md4.c alg-sha1.c --endif -- --check_PROGRAMS += \ -- test-alg-des test-alg-md5 test-crypt-des test-crypt-md5 \ -- test-crypt-badsalt -- --if ENABLE_WEAK_NON_GLIBC_HASHES --check_PROGRAMS += \ -- test-alg-hmac-sha1 test-alg-md4 test-alg-sha1 \ -- test-crypt-nthash test-crypt-sunmd5 test-crypt-pbkdf1-sha1 --endif --endif -+ test-alg-des test-alg-hmac-sha1 test-alg-md4 test-alg-md5 \ -+ test-alg-sha1 test-alg-sha256 test-alg-sha512 \ -+ test-crypt-badsalt test-crypt-bcrypt test-crypt-des \ -+ test-crypt-md5 test-crypt-nonnull test-crypt-nthash \ -+ test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \ -+ test-crypt-sunmd5 \ -+ test-byteorder test-gensalt - - if ENABLE_OBSOLETE_API - libcrypt_la_SOURCES += crypt-des-obsolete.c -@@ -187,7 +182,11 @@ test_alg_sha256_LDADD = alg-sha256.lo - test_alg_sha512_LDADD = alg-sha512.lo - - --# Every object file in the library depends on crypt-symbol-vers.h, --# which is a generated file, so automatic dependency generation will --# not detect it. --$(libcrypt_la_OBJECTS): crypt-symbol-vers.h -+# Every object file depends on crypt-symbol-vers.h and crypt-hashes.h, -+# which are generated files, so automatic dependency generation is not -+# sufficient. Most of the test programs depend on either libcrypt.la -+# or one of its components, so they do not need an explicit dependency -+# (after the first *successful* build, automatic dependency generation -+# will reveal the direct dependency) but a few don't. -+$(libcrypt_la_OBJECTS): crypt-symbol-vers.h crypt-hashes.h -+$(test_byteorder_OBJECTS): crypt-symbol-vers.h crypt-hashes.h -diff --git a/README.md b/README.md -index 869d46f..9211a33 100644 ---- a/README.md -+++ b/README.md -@@ -92,11 +92,13 @@ Linux. We are willing to consider adding binary backward - compatibility for other operating systems' existing libcrypts, but we - don't currently plan to do that work ourselves. - --It is also possible to remove support for DES, MD5, NTHASH and SUNMD5 --password hashes, by supplying the `--disable-weak-hashes` switch to --`configure`. This option implies `--disable-obsolete-api`. It should --only be used in contexts where there are definitely no user accounts --that are old enough to have stored their password with an old hash. -+Individual hash functions may be enabled or disabled by use of the -+`--enable-hashes` switch to `configure`. The default is to enable all -+supported hashes. Disabling the traditional 'des' hash algorithm -+implies `--disable-obsolete-api`. Security-conscious environments -+without backward compatibility constraints are encouraged to use -+`--enable-hashes=strong`, which enables only the hash functions that -+are strong enough to be safe for newly hashed passwords. - - The original implementation of the SUNMD5 hashing algorithm has a bug, - which is mimicked by libxcrypt to be fully compatible with hashes -diff --git a/alg-des-tables.c b/alg-des-tables.c -index 0bf9c88..c46d1c4 100644 ---- a/alg-des-tables.c -+++ b/alg-des-tables.c -@@ -49,6 +49,8 @@ - #include "crypt-port.h" - #include "alg-des.h" - -+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big -+ - const uint8_t m_sbox[4][4096] = { - { - 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2, -@@ -3842,3 +3844,5 @@ const uint32_t psbox[4][256] = { - 0x0a100421, 0x0a100c21, 0x0a120421, 0x0a120c21, - }, - }; -+ -+#endif -diff --git a/alg-des.c b/alg-des.c -index 3e62fe2..959d0f7 100644 ---- a/alg-des.c -+++ b/alg-des.c -@@ -59,6 +59,9 @@ - */ - - #include "crypt-port.h" -+ -+#if INCLUDE_des || INCLUDE_des_big || INCLUDE_des_xbsd -+ - #include "alg-des.h" - #include "byteorder.h" - -@@ -261,3 +264,5 @@ des_crypt_block (struct des_ctx *restrict ctx, - cpu_to_be32 (out, l_out); - cpu_to_be32 (out + 4, r_out); - } -+ -+#endif -diff --git a/alg-hmac-sha1.c b/alg-hmac-sha1.c -index 2940774..0b22163 100644 ---- a/alg-hmac-sha1.c -+++ b/alg-hmac-sha1.c -@@ -37,6 +37,8 @@ - - #include - -+#if INCLUDE_sha1 -+ - /* Don't change these */ - #define HMAC_IPAD 0x36 - #define HMAC_OPAD 0x5c -@@ -125,3 +127,5 @@ hmac_sha1_process_data (const uint8_t *text, size_t text_len, - sha1_process_bytes (resbuf, &ctx, HASH_LENGTH); - sha1_finish_ctx(&ctx, resbuf); - } -+ -+#endif -diff --git a/alg-md4.c b/alg-md4.c -index 56367df..ce62490 100644 ---- a/alg-md4.c -+++ b/alg-md4.c -@@ -19,6 +19,8 @@ - #include "alg-md4.h" - #include "byteorder.h" - -+#if INCLUDE_nthash -+ - /* - * The basic MD4 functions. - */ -@@ -250,3 +252,5 @@ md4_finish_ctx (struct md4_ctx *ctx, void *resbuf) - - return md4_read_ctx (ctx, resbuf); - } -+ -+#endif -diff --git a/alg-md5.c b/alg-md5.c -index e9b3412..df49fc6 100644 ---- a/alg-md5.c -+++ b/alg-md5.c -@@ -23,6 +23,7 @@ - #include "alg-md5.h" - #include "byteorder.h" - -+#if INCLUDE_md5 || INCLUDE_sunmd5 - - static void md5_process_block (const void *buffer, size_t len, - struct md5_ctx *ctx); -@@ -303,3 +304,5 @@ md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) - ctx->C = C; - ctx->D = D; - } -+ -+#endif -diff --git a/alg-sha1.c b/alg-sha1.c -index 13ff75a..421ffbd 100644 ---- a/alg-sha1.c -+++ b/alg-sha1.c -@@ -72,6 +72,7 @@ modified for use with libxcrypt - #include "crypt-port.h" - #include "alg-sha1.h" - -+#if INCLUDE_sha1 - - #define SHA1_DIGEST_SIZE 20 - -@@ -278,3 +279,5 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) - - return resbuf; - } -+ -+#endif -diff --git a/alg-sha256.c b/alg-sha256.c -index d4921a5..713385d 100644 ---- a/alg-sha256.c -+++ b/alg-sha256.c -@@ -22,6 +22,7 @@ - #include "alg-sha256.h" - #include "byteorder.h" - -+#if INCLUDE_sha256 - - /* Constants for SHA256 from FIPS 180-2:4.2.2. */ - static const uint32_t K[64] = -@@ -251,3 +252,5 @@ sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx) - ctx->buflen = (uint32_t)left_over; - } - } -+ -+#endif -diff --git a/alg-sha512.c b/alg-sha512.c -index 5010bc4..6a6aab2 100644 ---- a/alg-sha512.c -+++ b/alg-sha512.c -@@ -22,6 +22,7 @@ - #include "alg-sha512.h" - #include "byteorder.h" - -+#if INCLUDE_sha512 - - /* Constants for SHA512 from FIPS 180-2:4.2.3. */ - static const uint64_t K[80] = -@@ -284,3 +285,5 @@ sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) - ctx->buflen = (uint32_t)left_over; - } - } -+ -+#endif -diff --git a/configure.ac b/configure.ac -index f843b51..119f171 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -201,35 +201,35 @@ AC_ARG_ENABLE([obsolete-api], - [enable_obsolete_api=1] - ) - --AC_ARG_ENABLE([weak-hashes], -+AC_ARG_ENABLE([hashes], - AS_HELP_STRING( -- [--enable-weak-hashes[=ARG]], -- [When set to "yes", all of the hashing methods documented in crypt(5) -- are supported for authenticating existing password hashes, including -- several that are too weak to use for new passwords. -- -- When set to "glibc", only the weak hashes supported by historic -- versions of GNU libc are supported: traditional DES and FreeBSD-style -- MD5, but not bigcrypt-DES, BSDi extended DES, SHA1, SUNMD5, or NTHASH. -- -- When set to "no", only bcrypt, SHA512, and SHA256 are supported. -- This mode implies --disable-obsolete-api and breaks binary -- compatibility with glibc's libcrypt. -- -- [default=yes]] -+ [--enable-hashes=HASHES], -+ [Select hash algorithms to support. Acceptable values are -+ 'all' or a comma-separated list of names from the file -+ 'hashes.lst' and/or the keywords 'strong' and 'glibc', which -+ select groups of hashes as described in that file. The -+ default is 'all'. Note: if binary compatibility with glibc's -+ libcrypt is desired, the 'des' hash must be enabled.] - ), -- [case "${enableval}" in -- yes) enable_weak_hashes=1; enable_weak_non_glibc_hashes=1 ;; -- glibc) enable_weak_hashes=1; enable_weak_non_glibc_hashes=0 ;; -- no) enable_weak_hashes=0; enable_weak_non_glibc_hashes=0 ;; -- *) AC_MSG_ERROR([bad value ${enableval} for --enable-weak-hashes]) ;; -- esac], -- [enable_weak_hashes=1; enable_weak_non_glibc_hashes=1] -+ [hashes_selected=$enableval], -+ [hashes_selected=all] - ) -+# This code must run after AC_PROG_AWK. -+hashes_enabled=$( -+ $AWK -f ${srcdir}/sel-hashes.awk -v SELECTED_HASHES="$hashes_selected" \ -+ ${srcdir}/hashes.lst -+) -+if test x"$hashes_enabled" = x || test x"$hashes_enabled" = x,; then -+ AC_MSG_ERROR([bad value '${hashes_selected}' for --enable-hashes]) -+fi -+AC_SUBST([hashes_enabled]) - --# If weak hashes are disabled, then the obsolete APIs won't work anyway --# (they're all DES-specific). --if test $enable_weak_hashes = 0; then enable_obsolete_api=0; fi -+# If the traditional DES hash is disabled, then the obsolete APIs are -+# implicitly disabled. -+case "$hashes_enabled" in -+ *,des,*) ;; -+ *) enable_obsolete_api=0 ;; -+esac - - # The obsolete APIs are unconditionally excluded from the static library, - # so if we are not building the shared library, we are effectively not -@@ -298,15 +298,6 @@ AC_DEFINE_UNQUOTED([ENABLE_OBSOLETE_API], [$enable_obsolete_api], - should be included, 0 otherwise.]) - AM_CONDITIONAL([ENABLE_OBSOLETE_API], [test $enable_obsolete_api = 1]) - --AC_DEFINE_UNQUOTED([ENABLE_WEAK_HASHES], [$enable_weak_hashes], -- [Define as 1 if weak hashes (DES, MD5) should be included, 0 otherwise. -- If this is 0, ENABLE_OBSOLETE_API must also be 0.]) --AM_CONDITIONAL([ENABLE_WEAK_HASHES], [test $enable_weak_hashes = 1]) -- --AC_DEFINE_UNQUOTED([ENABLE_WEAK_NON_GLIBC_HASHES], [$enable_weak_non_glibc_hashes], -- [Define as 1 if weak hashes not supported by glibc should be included, 0 otherwise.]) --AM_CONDITIONAL([ENABLE_WEAK_NON_GLIBC_HASHES], [test $enable_weak_non_glibc_hashes = 1]) -- - # The Makefile needs to know which versions of the library we are building. - AM_CONDITIONAL([ENABLE_STATIC], [test $enable_static = yes]) - AM_CONDITIONAL([ENABLE_SHARED], [test $enable_shared = yes]) -diff --git a/crypt-bcrypt.c b/crypt-bcrypt.c -index f41a893..d468399 100644 ---- a/crypt-bcrypt.c -+++ b/crypt-bcrypt.c -@@ -50,6 +50,8 @@ - #include - #include - -+#if INCLUDE_bcrypt -+ - #if defined(__i386__) || defined(__x86_64__) || \ - defined(__alpha__) || defined(__hppa__) - #define BF_SCALE 1 -@@ -1007,3 +1009,5 @@ gensalt_bcrypt_y_rn (unsigned long count, - { - BF_gensalt ('y', count, rbytes, nrbytes, output, o_size); - } -+ -+#endif -diff --git a/crypt-des.c b/crypt-des.c -index 79b3144..3d8bc2e 100644 ---- a/crypt-des.c -+++ b/crypt-des.c -@@ -49,6 +49,8 @@ - - #include - -+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big -+ - #define DES_TRD_OUTPUT_LEN 14 /* SShhhhhhhhhhh0 */ - #define DES_EXT_OUTPUT_LEN 21 /* _CCCCSSSShhhhhhhhhhh0 */ - #define DES_BIG_OUTPUT_LEN ((16*11) + 2 + 1) /* SS (hhhhhhhhhhh){1,16} 0 */ -@@ -142,15 +144,14 @@ des_gen_hash (struct des_ctx *ctx, uint32_t count, uint8_t *output, - while (sptr < end); - *output = '\0'; - } -+#endif - -+#if INCLUDE_des - /* The original UNIX DES-based password hash, no extensions. */ --#if ENABLE_WEAK_NON_GLIBC_HASHES --static --#endif - void --crypt_des_trd_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size) -+crypt_des_rn (const char *phrase, const char *setting, -+ uint8_t *output, size_t o_size, -+ void *scratch, size_t s_size) - { - /* This shouldn't ever happen, but... */ - if (o_size < DES_TRD_OUTPUT_LEN || s_size < sizeof (struct des_buffer)) -@@ -194,8 +195,9 @@ crypt_des_trd_rn (const char *phrase, const char *setting, - des_set_salt (ctx, salt); - des_gen_hash (ctx, 25, cp, pkbuf); - } -+#endif - --#if ENABLE_WEAK_NON_GLIBC_HASHES -+#if INCLUDE_des_big - /* This algorithm is algorithm 0 (default) shipped with the C2 secure - implementation of Digital UNIX. - -@@ -212,11 +214,23 @@ crypt_des_trd_rn (const char *phrase, const char *setting, - (that is, the password can be no more than 128 characters long). - - Andy Phillips */ --static void -+void - crypt_des_big_rn (const char *phrase, const char *setting, - uint8_t *output, size_t o_size, - void *scratch, size_t s_size) - { -+#if INCLUDE_des -+ /* For backward compatibility, if the setting string is short enough -+ to have been generated by the traditional DES algorithm, forward -+ to traditional DES (which means that only the first 8 characters -+ of 'phrase' are significant). */ -+ if (strlen (setting) <= 13) -+ { -+ crypt_des_rn (phrase, setting, output, o_size, scratch, s_size); -+ return; -+ } -+#endif -+ - /* This shouldn't ever happen, but... */ - if (o_size < DES_BIG_OUTPUT_LEN || s_size < sizeof (struct des_buffer)) - { -@@ -264,19 +278,9 @@ crypt_des_big_rn (const char *phrase, const char *setting, - cp += 11; - } - } -+#endif - --/* crypt_rn() entry point for both the original UNIX password hash, -- with its 8-character length limit, and the Digital UNIX "bigcrypt" -- extension to permit longer passwords. */ --void --crypt_des_trd_or_big_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size) --{ -- (strlen (setting) > 13 ? crypt_des_big_rn : crypt_des_trd_rn) -- (phrase, setting, output, o_size, scratch, s_size); --} -- -+#if INCLUDE_des_xbsd - /* crypt_rn() entry point for BSD-style extended DES hashes. These - permit long passwords and have more salt and a controllable iteration - count, but are still unacceptably weak by modern standards. */ -@@ -346,12 +350,13 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting, - des_set_salt (ctx, salt); - des_gen_hash (ctx, count, cp, pkbuf); - } --#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */ -+#endif - -+#if INCLUDE_des || INCLUDE_des_big - void --gensalt_des_trd_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t output_size) -+gensalt_des_rn (unsigned long count, -+ const uint8_t *rbytes, size_t nrbytes, -+ uint8_t *output, size_t output_size) - { - if (output_size < 3) - { -@@ -369,8 +374,12 @@ gensalt_des_trd_rn (unsigned long count, - output[1] = ascii64[(unsigned int) rbytes[1] & 0x3f]; - output[2] = '\0'; - } -+#if INCLUDE_des_big -+strong_alias (gensalt_des_rn, gensalt_des_big_rn); -+#endif -+#endif - --#if ENABLE_WEAK_NON_GLIBC_HASHES -+#if INCLUDE_des_xbsd - void - gensalt_des_xbsd_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, -@@ -412,4 +421,4 @@ gensalt_des_xbsd_rn (unsigned long count, - - output[9] = '\0'; - } --#endif /* ENABLE_WEAK_NON_GLIBC_HASHES */ -+#endif -diff --git a/crypt-gensalt.c b/crypt-gensalt.c -index cfd596c..fb5b12c 100644 ---- a/crypt-gensalt.c -+++ b/crypt-gensalt.c -@@ -14,6 +14,8 @@ - #include - #include - -+#if INCLUDE_sha256 || INCLUDE_sha512 -+ - static const unsigned char _xcrypt_itoa64[64 + 1] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -@@ -90,3 +92,5 @@ gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount, - - output[written] = '\0'; - } -+ -+#endif -diff --git a/crypt-md5.c b/crypt-md5.c -index 9ae22da..1a9139a 100644 ---- a/crypt-md5.c -+++ b/crypt-md5.c -@@ -23,6 +23,7 @@ - - #include - -+#if INCLUDE_md5 - - /* Define our magic string to mark salt for MD5 "encryption" - replacement. This is meant to be the same as for other MD5 based -@@ -216,3 +217,5 @@ gensalt_md5_rn (unsigned long count, - gensalt_sha_rn ('1', 8, 1000, 1000, 1000, - count, rbytes, nrbytes, output, output_size); - } -+ -+#endif -diff --git a/crypt-nthash.c b/crypt-nthash.c -index 9d43232..f9fee7b 100644 ---- a/crypt-nthash.c -+++ b/crypt-nthash.c -@@ -42,6 +42,8 @@ - #include - #include - -+#if INCLUDE_nthash -+ - /* - * NT HASH = md4(str2unicode(phrase)) - */ -@@ -145,3 +147,5 @@ gensalt_nthash_rn (unsigned long count, - memcpy (output, salt, 15); - memcpy (output + 15, hashstr, 14); - } -+ -+#endif -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index b55d233..544d890 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -35,6 +35,8 @@ - #include - #include - -+#if INCLUDE_sha1 -+ - /* - * The default iterations - should take >0s on a fast CPU - * but not be insane for a slow CPU. -@@ -258,3 +260,5 @@ gensalt_sha1_rn (unsigned long count, - output[n + (c * enclen)] = '$'; - output[n + (c * enclen) + 1] = '\0'; - } -+ -+#endif -diff --git a/crypt-port.h b/crypt-port.h -index 8b21f56..6d94b09 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -191,69 +191,67 @@ void _xcrypt_secure_memset (void *s, size_t len) - #define symver_ref(extname, intname, version) \ - symver_set(extname, intname, version, "@") - -+/* Get the set of hash algorithms to be included and some related -+ definitions. */ -+#include "crypt-hashes.h" -+ -+ - /* Rename all of the internal-but-global symbols with a _crypt_ prefix - so that they do not interfere with other people's code when linking - statically. This list cannot be autogenerated, but is validated by - test-symbols.sh. */ - --#define crypt_bcrypt_rn _crypt_crypt_bcrypt_rn --#define gensalt_bcrypt_a_rn _crypt_gensalt_bcrypt_a_rn --#define gensalt_bcrypt_b_rn _crypt_gensalt_bcrypt_b_rn --#define gensalt_bcrypt_x_rn _crypt_gensalt_bcrypt_x_rn --#define gensalt_bcrypt_y_rn _crypt_gensalt_bcrypt_y_rn --#define gensalt_sha_rn _crypt_gensalt_sha_rn --#define gensalt_sha256_rn _crypt_gensalt_sha256_rn --#define gensalt_sha512_rn _crypt_gensalt_sha512_rn - #define get_random_bytes _crypt_get_random_bytes --#define crypt_sha256_rn _crypt_crypt_sha256_rn --#define crypt_sha512_rn _crypt_crypt_sha512_rn --#define sha256_finish_ctx _crypt_sha256_finish_ctx --#define sha256_init_ctx _crypt_sha256_init_ctx --#define sha256_process_bytes _crypt_sha256_process_bytes --#define sha512_finish_ctx _crypt_sha512_finish_ctx --#define sha512_init_ctx _crypt_sha512_init_ctx --#define sha512_process_bytes _crypt_sha512_process_bytes - --#if ENABLE_WEAK_HASHES --#define comp_maskl _crypt_comp_maskl --#define comp_maskr _crypt_comp_maskr --#if ENABLE_WEAK_NON_GLIBC_HASHES --#define crypt_des_trd_or_big_rn _crypt_crypt_des_trd_or_big_rn --#else --#define crypt_des_trd_rn _crypt_crypt_des_trd_rn --#endif --#define crypt_des_xbsd_rn _crypt_crypt_des_xbsd_rn --#define crypt_md5_rn _crypt_crypt_md5_rn --#define crypt_nthash_rn _crypt_crypt_nthash_rn --#define crypt_sha1_rn _crypt_crypt_sha1_rn --#define crypt_sunmd5_rn _crypt_crypt_sunmd5_rn -+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big - #define des_crypt_block _crypt_des_crypt_block - #define des_set_key _crypt_des_set_key - #define des_set_salt _crypt_des_set_salt -+#define comp_maskl _crypt_comp_maskl -+#define comp_maskr _crypt_comp_maskr - #define fp_maskl _crypt_fp_maskl - #define fp_maskr _crypt_fp_maskr --#define gensalt_des_trd_rn _crypt_gensalt_des_trd_rn --#define gensalt_des_xbsd_rn _crypt_gensalt_des_xbsd_rn --#define gensalt_md5_rn _crypt_gensalt_md5_rn --#define gensalt_nthash_rn _crypt_gensalt_nthash_rn --#define gensalt_sha1_rn _crypt_gensalt_sha1_rn --#define gensalt_sunmd5_rn _crypt_gensalt_sunmd5_rn - #define ip_maskl _crypt_ip_maskl - #define ip_maskr _crypt_ip_maskr - #define key_perm_maskl _crypt_key_perm_maskl - #define key_perm_maskr _crypt_key_perm_maskr --#define hmac_sha1_process_data _crypt_hmac_sha1_process_data -+#define m_sbox _crypt_m_sbox -+#define psbox _crypt_psbox -+#endif -+ -+#if INCLUDE_nthash - #define md4_finish_ctx _crypt_md4_finish_ctx - #define md4_init_ctx _crypt_md4_init_ctx - #define md4_process_bytes _crypt_md4_process_bytes -+#endif -+ -+#if INCLUDE_md5 || INCLUDE_sunmd5 - #define md5_finish_ctx _crypt_md5_finish_ctx - #define md5_init_ctx _crypt_md5_init_ctx - #define md5_process_bytes _crypt_md5_process_bytes --#define m_sbox _crypt_m_sbox --#define psbox _crypt_psbox -+#endif -+ -+#if INCLUDE_sha1 -+#define hmac_sha1_process_data _crypt_hmac_sha1_process_data - #define sha1_finish_ctx _crypt_sha1_finish_ctx - #define sha1_init_ctx _crypt_sha1_init_ctx - #define sha1_process_bytes _crypt_sha1_process_bytes - #endif - -+#if INCLUDE_sha256 -+#define sha256_finish_ctx _crypt_sha256_finish_ctx -+#define sha256_init_ctx _crypt_sha256_init_ctx -+#define sha256_process_bytes _crypt_sha256_process_bytes -+#endif -+ -+#if INCLUDE_sha512 -+#define sha512_finish_ctx _crypt_sha512_finish_ctx -+#define sha512_init_ctx _crypt_sha512_init_ctx -+#define sha512_process_bytes _crypt_sha512_process_bytes -+#endif -+ -+#if INCLUDE_sha256 || INCLUDE_sha512 -+#define gensalt_sha_rn _crypt_gensalt_sha_rn -+#endif -+ - #endif /* crypt-port.h */ -diff --git a/crypt-private.h b/crypt-private.h -index c5db3bd..7b2b232 100644 ---- a/crypt-private.h -+++ b/crypt-private.h -@@ -36,86 +36,4 @@ extern void gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount, - this big. */ - #define ALG_SPECIFIC_SIZE 8192 - --/* Individual hash functions */ -- --#if ENABLE_WEAK_HASHES --extern void crypt_md5_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --#if ENABLE_WEAK_NON_GLIBC_HASHES --extern void crypt_des_trd_or_big_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --extern void crypt_des_xbsd_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --extern void crypt_nthash_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --extern void crypt_sha1_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --extern void crypt_sunmd5_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --#else --extern void crypt_des_trd_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --#endif --#endif -- --extern void crypt_sha256_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --extern void crypt_sha512_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); --extern void crypt_bcrypt_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size); -- --#if ENABLE_WEAK_HASHES --extern void gensalt_des_trd_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_md5_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --#if ENABLE_WEAK_NON_GLIBC_HASHES --extern void gensalt_des_xbsd_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_nthash_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_sha1_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_sunmd5_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --#endif --#endif -- --extern void gensalt_sha256_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_sha512_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); -- --extern void gensalt_bcrypt_a_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_bcrypt_b_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_bcrypt_x_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); --extern void gensalt_bcrypt_y_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size); -- - #endif /* crypt-private.h */ -diff --git a/crypt-sha256.c b/crypt-sha256.c -index 9fc70e1..8b4ba67 100644 ---- a/crypt-sha256.c -+++ b/crypt-sha256.c -@@ -24,6 +24,7 @@ - #include - #include - -+#if INCLUDE_sha256 - - /* Define our magic string to mark salt for SHA256 "encryption" - replacement. */ -@@ -283,3 +284,5 @@ gensalt_sha256_rn (unsigned long count, - gensalt_sha_rn ('5', SALT_LEN_MAX, ROUNDS_DEFAULT, ROUNDS_MIN, ROUNDS_MAX, - count, rbytes, nrbytes, output, output_size); - } -+ -+#endif -diff --git a/crypt-sha512.c b/crypt-sha512.c -index b4473da..28e4f1c 100644 ---- a/crypt-sha512.c -+++ b/crypt-sha512.c -@@ -24,6 +24,7 @@ - #include - #include - -+#if INCLUDE_sha512 - - /* Define our magic string to mark salt for SHA512 "encryption" - replacement. */ -@@ -297,3 +298,5 @@ gensalt_sha512_rn (unsigned long count, - gensalt_sha_rn ('6', SALT_LEN_MAX, ROUNDS_DEFAULT, ROUNDS_MIN, ROUNDS_MAX, - count, rbytes, nrbytes, output, output_size); - } -+ -+#endif -diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c -index 43054b9..fcd3984 100644 ---- a/crypt-sunmd5.c -+++ b/crypt-sunmd5.c -@@ -32,6 +32,9 @@ - #include - #include - -+#if INCLUDE_sunmd5 -+ -+ - #define CRYPT_ALGNAME "md5" - - /* minimum number of rounds we do, not including the per-user ones */ -@@ -419,3 +422,5 @@ crypt_sunmd5_rn (const char *phrase, const char *setting, - p += 2; - *p = '\0'; - } -+ -+#endif -diff --git a/crypt.c b/crypt.c -index 12d50fd..e1bfc5b 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -70,6 +70,7 @@ typedef void (*gensalt_fn) (unsigned long count, - struct hashfn - { - const char *prefix; -+ size_t plen; - crypt_fn crypt; - gensalt_fn gensalt; - /* The type of this field is unsigned char to ensure that it cannot -@@ -77,54 +78,12 @@ struct hashfn - unsigned char nrbytes; - }; - --/* This table should always begin with the algorithm that should be used -- for new encryptions. */ --static const struct hashfn tagged_hashes[] = -+static const struct hashfn hash_algorithms[] = - { -- /* bcrypt */ -- { "$2b$", crypt_bcrypt_rn, gensalt_bcrypt_b_rn, 16 }, -- { "$2a$", crypt_bcrypt_rn, gensalt_bcrypt_a_rn, 16 }, -- { "$2x$", crypt_bcrypt_rn, gensalt_bcrypt_x_rn, 16 }, -- { "$2y$", crypt_bcrypt_rn, gensalt_bcrypt_y_rn, 16 }, -- -- /* legacy hashes */ --#if ENABLE_WEAK_HASHES -- { "$1$", crypt_md5_rn, gensalt_md5_rn, 9 }, --#if ENABLE_WEAK_NON_GLIBC_HASHES -- { "$3$", crypt_nthash_rn, gensalt_nthash_rn, 16 }, -- { "$md5", crypt_sunmd5_rn, gensalt_sunmd5_rn, 8 }, -- { "$sha1", crypt_sha1_rn, gensalt_sha1_rn, 48 }, --#endif --#endif -- { "$5$", crypt_sha256_rn, gensalt_sha256_rn, 15 }, -- { "$6$", crypt_sha512_rn, gensalt_sha512_rn, 15 }, -- { 0, 0, 0, 0 } --}; -- --#if ENABLE_WEAK_HASHES --#if ENABLE_WEAK_NON_GLIBC_HASHES --/* BSD-style extended DES */ --static const struct hashfn bsdi_extended_hash = --{ -- "_", crypt_des_xbsd_rn, gensalt_des_xbsd_rn, 3 --}; -- --/* Traditional DES or bigcrypt-style extended DES */ --static const struct hashfn traditional_hash = --{ -- "", crypt_des_trd_or_big_rn, gensalt_des_trd_rn, 2 -+ HASH_ALGORITHM_TABLE_ENTRIES - }; - --#else -- --/* Traditional DES */ --static const struct hashfn traditional_hash = --{ -- "", crypt_des_trd_rn, gensalt_des_trd_rn, 2 --}; -- --#endif -- -+#if INCLUDE_des || INCLUDE_des_big - static int - is_des_salt_char (char c) - { -@@ -133,30 +92,29 @@ is_des_salt_char (char c) - (c >= '0' && c <= '9') || - c == '.' || c == '/'); - } --#endif /* ENABLE_WEAK_HASHES */ -+#endif - - static const struct hashfn * - get_hashfn (const char *setting) - { -- if (setting[0] == '$') -+ const struct hashfn *h; -+ for (h = hash_algorithms; h->prefix; h++) - { -- const struct hashfn *h; -- for (h = tagged_hashes; h->prefix; h++) -- if (!strncmp (setting, h->prefix, strlen (h->prefix))) -- return h; -- return 0; -- } --#if ENABLE_WEAK_HASHES --#if ENABLE_WEAK_NON_GLIBC_HASHES -- else if (setting[0] == '_') -- return &bsdi_extended_hash; --#endif -- else if (setting[0] == '\0' || -- (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1]))) -- return &traditional_hash; -+ if (h->plen > 0) -+ { -+ if (!strncmp (setting, h->prefix, h->plen)) -+ return h; -+ } -+#if INCLUDE_des || INCLUDE_des_big -+ else -+ { -+ if (setting[0] == '\0' || -+ (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1]))) -+ return h; -+ } - #endif -- else -- return 0; -+ } -+ return 0; - } - - /* For historical reasons, crypt and crypt_r are not expected ever to -@@ -392,9 +350,15 @@ crypt_gensalt_rn (const char *prefix, unsigned long count, - - /* If the prefix is 0, that means to use the current best default. - Note that this is different from the behavior when the prefix is -- "", which selects DES. */ -+ "", which selects DES. HASH_ALGORITHM_DEFAULT is null when the -+ current default algorithm was disabled at configure time. */ - if (!prefix) -- prefix = tagged_hashes[0].prefix; -+ prefix = HASH_ALGORITHM_DEFAULT; -+ if (!prefix) -+ { -+ errno = EINVAL; -+ return 0; -+ } - - const struct hashfn *h = get_hashfn (prefix); - if (!h) -diff --git a/gen-hashes.awk b/gen-hashes.awk -new file mode 100644 -index 0000000..39faf8e ---- /dev/null -+++ b/gen-hashes.awk -@@ -0,0 +1,160 @@ -+# Generate crypt-hashes.h from hashes.lst and configure settings. -+# -+# Copyright 2018 Zack Weinberg -+# -+# This library is free software; you can redistribute it and/or -+# modify it under the terms of the GNU Lesser General Public License -+# as published by the Free Software Foundation; either version 2.1 of -+# the License, or (at your option) any later version. -+# -+# This library is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU Lesser General Public License for more details. -+# -+# You should have received a copy of the GNU Lesser General Public -+# License along with this library; if not, see -+# . -+ -+BEGIN { -+ default_prefix = ":" -+ next_output = 0 -+ error = 0 -+} -+ -+/^#/ { -+ next -+} -+ -+{ -+ if (!($1 in hash_enabled)) { -+ output_order[next_output++] = $1 -+ hash_enabled[$1] = 0 -+ } -+ if ($1 == ":") { -+ printf("%s:%d: name cannot be blank\n", FILENAME, NR) -+ error = 1 -+ } -+ if ($4 !~ /^[0-9]+$/ || $4 == 0) { -+ printf("%s:%d: nrbytes must be a positive integer\n", FILENAME, NR) -+ error = 1 -+ } -+ if ($2 == ":") $2 = "" -+ if ($3 == ":") $3 = "" -+ if ($5 == ":") $5 = "" -+ -+ crypt_fn = "crypt_" $1 "_rn" -+ gensalt_fn = "gensalt_" $1 $2 "_rn" -+ -+ if (!(crypt_fn in prototyped)) { -+ prototyped[crypt_fn] = 1 -+ renames[$1] = renames[$1] \ -+ "#define " crypt_fn " _crypt_" crypt_fn "\n" -+ prototypes[$1] = prototypes[$1] \ -+ "extern void " crypt_fn "\n " \ -+ "(const char *, const char *, uint8_t *, size_t, void *, size_t);\n" -+ } -+ if (!(gensalt_fn in prototyped)) { -+ prototyped[gensalt_fn] = 1 -+ renames[$1] = renames[$1] \ -+ "#define " gensalt_fn " _crypt_" gensalt_fn "\n" -+ prototypes[$1] = prototypes[$1] \ -+ "extern void " gensalt_fn "\n " \ -+ "(unsigned long, const uint8_t *, size_t, uint8_t *, size_t);\n" -+ } -+ -+ entry = sprintf(" { \"%s\", %d, %s, %s, %d }, \\\n", -+ $3, length($3), crypt_fn, gensalt_fn, $4) -+ table_entries[$1] = table_entries[$1] entry -+ -+ split($5, flags, ",") -+ for (i in flags) { -+ flag = flags[i] -+ if (flag == "DEFAULT") { -+ if (default_prefix == ":") { -+ default_hash = $1 -+ default_prefix = $3 -+ default_prefix_line = NR -+ } else { -+ printf("%s:%d: error: 'DEFAULT' specified twice\n", -+ FILENAME, NR) > "/dev/stderr" -+ printf("%s:%d: note: previous 'DEFAULT' was here\n", -+ FILENAME, default_prefix_line) > "/dev/stderr" -+ error = 1 -+ } -+ } else if (flag == "STRONG" || flag == "GLIBC") { -+ # handled in sel-hashes.awk -+ } else { -+ printf("%s:%d: unrecognized flag %s\n", FILENAME, NR, flag) \ -+ > "/dev/stderr" -+ error = 1 -+ } -+ } -+} -+ -+ -+END { -+ if (error) { -+ exit 1 -+ } -+ -+ # ENABLED_HASHES is set on the command line. -+ split(ENABLED_HASHES, enabled_hashes_list, ",") -+ for (i in enabled_hashes_list) { -+ h = enabled_hashes_list[i] -+ if (h != "") { -+ hash_enabled[h] = 1 -+ } -+ } -+ -+ if (default_prefix == ":") { -+ print "error: no default hash selected" > "/dev/stderr" -+ exit 1 -+ } -+ -+ print "/* Generated by genhashes.awk from hashes.lst. DO NOT EDIT. */" -+ print "" -+ print "#ifndef _CRYPT_HASHES_H" -+ print "#define _CRYPT_HASHES_H 1" -+ -+ print "" -+ for (i in output_order) { -+ hash = output_order[i] -+ printf("#define INCLUDE_%-8s %d\n", hash, hash_enabled[hash]) -+ } -+ -+ print "" -+ print "/* Internal symbol renames for static linkage, see crypt-port.h. */" -+ for (i in output_order) { -+ hash = output_order[i] -+ if (hash_enabled[hash]) { -+ print renames[hash] -+ } -+ } -+ -+ print "/* Prototypes for hash algorithm entry points. */" -+ for (i in output_order) { -+ hash = output_order[i] -+ if (hash_enabled[hash]) { -+ print prototypes[hash] -+ } -+ } -+ -+ print "#define HASH_ALGORITHM_TABLE_ENTRIES \\" -+ for (i in output_order) { -+ hash = output_order[i] -+ if (hash_enabled[hash]) { -+ printf("%s", table_entries[hash]) -+ } -+ } -+ print " { 0, 0, 0, 0, 0 }" -+ -+ print "" -+ if (hash_enabled[default_hash]) { -+ print "#define HASH_ALGORITHM_DEFAULT \"" default_prefix "\"" -+ } else { -+ print "#define HASH_ALGORITHM_DEFAULT 0" -+ } -+ print "" -+ print "#endif /* crypt-hashes.h */" -+} -diff --git a/hashes.lst b/hashes.lst -new file mode 100644 -index 0000000..488768f ---- /dev/null -+++ b/hashes.lst -@@ -0,0 +1,40 @@ -+# This file is read by genhashes.awk and by the configure script. -+# -+# It lists, for each supported hash algorithm, the name to be used to -+# enable or disable it at configure time, which is also part of the -+# name used for the 'crypt_fn' and 'gensalt_fn' entry points to the -+# relevant algorithm module; an optional suffix on the name of the -+# 'gensalt_fn'; the prefix used to identify the algorithm in hash -+# strings; the number of bytes of random data required to generate a -+# salt; and a set of flags. Currently there are three flags: DEFAULT -+# means this is the hash to use when no prefix was supplied to -+# crypt_gensalt, STRONG means the hash is still considered strong -+# enough to use for newly hashed passwords, and GLIBC means the hash -+# was historically supported by GNU libc's libcrypt. -+# -+# Fields are separated by whitespace. Lines beginning with # are -+# ignored; # is not otherwise significant. Multiple flags are -+# separated by commas. A field whose contents are a single colon (:) -+# is actually understood as an empty string; colon is used for this -+# purpose because it cannot be part of a hash prefix or a C identifier. -+# -+# Note: All entries with the same name should be consecutive. -+# -+# Note: crypt() checks prefixes in the order they appear in this file, -+# and the first match wins. Therefore, the empty prefix (traditional -+# DES) must be last. -+# -+#name gs_suffix h_prefix nrbytes flags -+bcrypt _b $2b$ 16 STRONG,DEFAULT -+bcrypt _a $2a$ 16 STRONG -+bcrypt _x $2x$ 16 STRONG -+bcrypt _y $2y$ 16 STRONG -+sha512 : $6$ 15 STRONG,GLIBC -+sha256 : $5$ 15 STRONG,GLIBC -+md5 : $1$ 9 GLIBC -+sunmd5 : $md5 8 : -+sha1 : $sha1 48 : -+nthash : $3$ 16 : -+des_xbsd : _ 3 : -+des_big : : 2 : -+des : : 2 GLIBC -diff --git a/sel-hashes.awk b/sel-hashes.awk -new file mode 100644 -index 0000000..c4edcbb ---- /dev/null -+++ b/sel-hashes.awk -@@ -0,0 +1,89 @@ -+# Expand a list of selected hashes to a list of enabled hashes, using -+# the information in hashes.lst. -+# -+# Copyright 2018 Zack Weinberg -+# -+# This library is free software; you can redistribute it and/or -+# modify it under the terms of the GNU Lesser General Public License -+# as published by the Free Software Foundation; either version 2.1 of -+# the License, or (at your option) any later version. -+# -+# This library is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU Lesser General Public License for more details. -+# -+# You should have received a copy of the GNU Lesser General Public -+# License along with this library; if not, see -+# . -+ -+BEGIN { -+ enable_all = 0 -+ enable_strong = 0 -+ enable_glibc = 0 -+ enable_some = 0 -+ error = 0 -+ split(SELECTED_HASHES, selected_hashes_list, ",") -+ for (i in selected_hashes_list) { -+ h = selected_hashes_list[i] -+ if (h == "all") { -+ enable_all = 1 -+ } else if (h == "strong") { -+ enable_strong = 1 -+ } else if (h == "glibc") { -+ enable_glibc = 1 -+ } else { -+ enable_some = 1 -+ selected_hashes[h] = 1 -+ } -+ } -+ if (enable_all && (enable_strong || enable_glibc || enable_some)) { -+ error = 1 -+ exit 1 -+ } -+} -+ -+/^#/ { -+ next -+} -+ -+{ -+ if (enable_all || $1 in selected_hashes) { -+ enabled_hashes[$1] = 1 -+ } else { -+ enabled_hashes[$1] = 0 -+ -+ split($5, flags, ",") -+ for (i in flags) { -+ flag = flags[i] -+ if (flag == "STRONG" && enable_strong) { -+ enabled_hashes[$1] = 1 -+ } else if (flag == "GLIBC" && enable_glibc) { -+ enabled_hashes[$1] = 1 -+ } -+ } -+ } -+} -+ -+ -+END { -+ if (error) { -+ exit 1 -+ } -+ -+ # Check for individual selected hashes that didn't appear in -+ # hashes.lst. -+ for (h in selected_hashes) { -+ if (!(h in enabled_hashes)) { -+ exit 1 -+ } -+ } -+ -+ enabled_hash_list = "," -+ for (i in enabled_hashes) { -+ if (enabled_hashes[i]) { -+ enabled_hash_list = enabled_hash_list i "," -+ } -+ } -+ print enabled_hash_list -+} -diff --git a/test-alg-des.c b/test-alg-des.c -index 2f42870..d00fdb5 100644 ---- a/test-alg-des.c -+++ b/test-alg-des.c -@@ -11,6 +11,8 @@ - - #include - -+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big -+ - static void - v_print (const unsigned char v[8]) - { -@@ -66,3 +68,13 @@ main (void) - - return status; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-alg-hmac-sha1.c b/test-alg-hmac-sha1.c -index 777ac86..21ef281 100644 ---- a/test-alg-hmac-sha1.c -+++ b/test-alg-hmac-sha1.c -@@ -33,6 +33,8 @@ - #include - #include - -+#if INCLUDE_sha1 -+ - #define HASH_LENGTH 20 - - static char * -@@ -166,3 +168,13 @@ main (void) - } - return n; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-alg-md4.c b/test-alg-md4.c -index ab6ad87..1b1b828 100644 ---- a/test-alg-md4.c -+++ b/test-alg-md4.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_nthash -+ - static const struct - { - const char *input; -@@ -97,3 +99,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-alg-md5.c b/test-alg-md5.c -index 9908ab8..dabc6ba 100644 ---- a/test-alg-md5.c -+++ b/test-alg-md5.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_md5 || INCLUDE_sunmd5 -+ - static const struct - { - const char *input; -@@ -120,3 +122,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-alg-sha1.c b/test-alg-sha1.c -index 04ce456..594d192 100644 ---- a/test-alg-sha1.c -+++ b/test-alg-sha1.c -@@ -9,6 +9,8 @@ - - #include - -+#if INCLUDE_sha1 -+ - /* Test Vectors (from FIPS PUB 180-1) */ - const char *test_data[3] = - { -@@ -80,3 +82,13 @@ main (void) - /* success */ - return retval; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-alg-sha256.c b/test-alg-sha256.c -index 45345e2..06354ac 100644 ---- a/test-alg-sha256.c -+++ b/test-alg-sha256.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_sha256 -+ - static const struct - { - const char *input; -@@ -129,3 +131,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-alg-sha512.c b/test-alg-sha512.c -index 0e24ad5..b6d4fc6 100644 ---- a/test-alg-sha512.c -+++ b/test-alg-sha512.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_sha512 -+ - static const struct - { - const char *input; -@@ -159,3 +161,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c -index a5e0e01..8ce7401 100644 ---- a/test-crypt-badsalt.c -+++ b/test-crypt-badsalt.c -@@ -25,7 +25,9 @@ - - static const char *tests[][3] = - { -+#if INCLUDE_des || INCLUDE_des_big - { "no salt", "", "..ogcgXxFhnjI" /* valid setting */ }, -+#endif - { "single char", "/", "*0" /* invalid setting */ }, - { "first char bad", "!x", "*0" /* invalid setting */ }, - { "second char bad", "Z%", "*0" /* invalid setting */ }, -diff --git a/test-crypt-bcrypt.c b/test-crypt-bcrypt.c -index 02a2f07..c984e4d 100644 ---- a/test-crypt-bcrypt.c -+++ b/test-crypt-bcrypt.c -@@ -21,6 +21,8 @@ - #include - #include - -+#if INCLUDE_bcrypt -+ - static const char *tests[][3] = - { - { -@@ -259,3 +261,13 @@ main (void) - free (data); - return status; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-des.c b/test-crypt-des.c -index e541885..1b5463e 100644 ---- a/test-crypt-des.c -+++ b/test-crypt-des.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big -+ - static const struct - { - const char *salt; -@@ -10,6 +12,7 @@ static const struct - const char *input; - } tests[] = - { -+#if INCLUDE_des - /* traditional-DES test vectors from John the Ripper */ - { "CC", "CCNf8Sbh3HDfQ", "U*U*U*U*" }, - { "CC", "CCNf8Sbh3HDfQ", "U*U*U*U*ignored" }, -@@ -19,8 +22,9 @@ static const struct - { "CC", "CC4rMpbg9AMZ.", "\xd5\xaa\xd5\xaa\xaa\xaa\xd5\xaa" }, - { "XX", "XXxzOu6maQKqQ", "*U*U*U*U" }, - { "SD", "SDbsugeBiC58A", "" }, -+#endif - --#if ENABLE_WEAK_NON_GLIBC_HASHES -+#if INCLUDE_des_xbsd - /* BSDI-extended-DES, ditto */ - { "_J9..CCCC", "_J9..CCCCXBrJUJV154M", "U*U*U*U*" }, - { "_J9..CCCC", "_J9..CCCCXUhOBTXzaiE", "U*U***U" }, -@@ -38,7 +42,9 @@ static const struct - { "_J9..SDiz", "_J9..SDizxmRI1GjnQuE", "zxyDPWgydbQjgq" }, - { "_K9..Salt", "_K9..SaltNrQgIYUAeoY", "726 even" }, - { "_J9..SDSD", "_J9..SDSD5YGyRCr4W4c", "" }, -+#endif - -+#if INCLUDE_des_big - /* 10 bigcrypt test vectors from pw-fake-unix.gz from the openwall - wiki. All have two blocks. The salt is padded with dots because - crypt_r will only use bigcrypt if the setting string begins with -@@ -100,3 +106,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-md5.c b/test-crypt-md5.c -index 235c250..3035c39 100644 ---- a/test-crypt-md5.c -+++ b/test-crypt-md5.c -@@ -1,6 +1,8 @@ - #include "crypt-port.h" - #include "crypt-base.h" - -+#if INCLUDE_md5 -+ - int - main (void) - { -@@ -17,3 +19,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-nthash.c b/test-crypt-nthash.c -index 6f897fe..9bf7d28 100644 ---- a/test-crypt-nthash.c -+++ b/test-crypt-nthash.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_nthash -+ - static const struct - { - const char *input; -@@ -160,3 +162,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-pbkdf1-sha1.c b/test-crypt-pbkdf1-sha1.c -index aadc0fe..677e5bf 100644 ---- a/test-crypt-pbkdf1-sha1.c -+++ b/test-crypt-pbkdf1-sha1.c -@@ -5,6 +5,8 @@ - #include - #include - -+#if INCLUDE_sha1 -+ - const char *password = "zyxwvuts"; - const char *tests[][2] = - { -@@ -92,3 +94,13 @@ main (void) - free (previous); - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-sha256.c b/test-crypt-sha256.c -index 23da81c..7c42398 100644 ---- a/test-crypt-sha256.c -+++ b/test-crypt-sha256.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_sha256 -+ - static const struct - { - const char *salt; -@@ -73,3 +75,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-sha512.c b/test-crypt-sha512.c -index 1aa0b71..c2a1973 100644 ---- a/test-crypt-sha512.c -+++ b/test-crypt-sha512.c -@@ -3,6 +3,8 @@ - - #include - -+#if INCLUDE_sha512 -+ - static const struct - { - const char *salt; -@@ -73,3 +75,13 @@ main (void) - - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-crypt-sunmd5.c b/test-crypt-sunmd5.c -index d67781b..2c9731a 100644 ---- a/test-crypt-sunmd5.c -+++ b/test-crypt-sunmd5.c -@@ -4,6 +4,8 @@ - #include - #include - -+#if INCLUDE_sunmd5 -+ - const char *password = "abcdefg"; - const char *tests[][3] = - { -@@ -128,3 +130,13 @@ main (void) - free (previous); - return result; - } -+ -+#else -+ -+int -+main (void) -+{ -+ return 77; /* UNSUPPORTED */ -+} -+ -+#endif -diff --git a/test-gensalt.c b/test-gensalt.c -index 2705671..b81fcf0 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -14,43 +14,56 @@ static const char *const entropy[] = - 0 - }; - --#if ENABLE_WEAK_HASHES -+#if INCLUDE_des || INCLUDE_des_big - static const char *const des_expected_output[] = { "Mp", "Pp", "ZH", "Uh"}; --static const char *const md5_expected_output[] = { -- "$1$MJHnaAke", -- "$1$PKXc3hCO", -- "$1$ZAFlICwY", -- "$1$UqGBkVu0" --}; --#if ENABLE_WEAK_NON_GLIBC_HASHES -+#endif -+#if INCLUDE_des_xbsd - static const char *const bsdi_expected_output[] = { - "_J9..MJHn", - "_J9..PKXc", - "_J9..ZAFl", - "_J9..UqGB" - }; -+#endif -+#if INCLUDE_md5 -+static const char *const md5_expected_output[] = { -+ "$1$MJHnaAke", -+ "$1$PKXc3hCO", -+ "$1$ZAFlICwY", -+ "$1$UqGBkVu0" -+}; -+#endif -+#if INCLUDE_nthash - static const char *const nthash_expected_output[] = { - "$3$__not_used__c809a450df09a3", - "$3$__not_used__30d0d6f834c0c3", - "$3$__not_used__0eeeebb83d6fe4", - "$3$__not_used__1c690d6a9ef88c" - }; -+#endif -+#if INCLUDE_sunmd5 - #define sunmd5_expected_output 0 /* output is not deterministic */ --#define pbkdf_expected_output 0 /* output is not deterministic */ - #endif -+#if INCLUDE_sha1 -+#define pbkdf_expected_output 0 /* output is not deterministic */ - #endif -+#if INCLUDE_sha256 - static const char *const sha256_expected_output[] = { - "$5$MJHnaAkegEVYHsFK", - "$5$PKXc3hCOSyMqdaEQ", - "$5$ZAFlICwYRETzIzIj", - "$5$UqGBkVu01rurVZqg" - }; -+#endif -+#if INCLUDE_sha512 - static const char *const sha512_expected_output[] = { - "$6$MJHnaAkegEVYHsFK", - "$6$PKXc3hCOSyMqdaEQ", - "$6$ZAFlICwYRETzIzIj", - "$6$UqGBkVu01rurVZqg" - }; -+#endif -+#if INCLUDE_bcrypt - static const char *const bcrypt_a_expected_output[] = { - "$2a$05$UBVLHeMpJ/QQCv3XqJx8zO", - "$2a$05$kxUgPcrmlm9XoOjvxCyfP.", -@@ -75,6 +88,7 @@ static const char *const bcrypt_y_expected_output[] = { - "$2y$05$HPNDjKMRFdR7zC87CMSmA.", - "$2y$05$mAyzaIeJu41dWUkxEbn8hO" - }; -+#endif - - struct testcase - { -@@ -86,22 +100,36 @@ struct testcase - - static const struct testcase testcases[] = - { --#if ENABLE_WEAK_HASHES -+#if INCLUDE_des || INCLUDE_des_big - { "", des_expected_output, 2, 0 }, // DES -- { "$1$", md5_expected_output, 11, 0 }, // MD5 --#if ENABLE_WEAK_NON_GLIBC_HASHES -+#endif -+#if INCLUDE_des_xbsd - { "_", bsdi_expected_output, 9, 0 }, // BSDi extended DES -+#endif -+#if INCLUDE_md5 -+ { "$1$", md5_expected_output, 11, 0 }, // MD5 -+#endif -+#if INCLUDE_nthash - { "$3$", nthash_expected_output, 29, 0 }, // NTHASH -+#endif -+#if INCLUDE_sunmd5 - { "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5 -- { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1 - #endif -+#if INCLUDE_sha1 -+ { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1 - #endif -+#if INCLUDE_sha256 - { "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256 -+#endif -+#if INCLUDE_sha512 - { "$6$", sha512_expected_output, 19, 0 }, // SHA-2-512 -+#endif -+#if INCLUDE_bcrypt - { "$2a$", bcrypt_a_expected_output, 29, 0 }, // bcrypt mode A - { "$2b$", bcrypt_b_expected_output, 29, 0 }, // bcrypt mode B - { "$2x$", bcrypt_x_expected_output, 29, 0 }, // bcrypt mode X - { "$2y$", bcrypt_y_expected_output, 29, 0 }, // bcrypt mode Y -+#endif - { 0, 0, 0, 0 } - }; - -@@ -184,7 +212,9 @@ main (void) - char *setting1, *setting2; - setting1 = crypt_gensalt_ra ("$2b$", 0, entropy[0], 16); - setting2 = crypt_gensalt_ra (0, 0, entropy[0], 16); -- if (strcmp (setting1, setting2)) -+ if ((setting1 == 0 && setting2 != 0) || -+ (setting1 != 0 && setting2 == 0) || -+ (setting1 != 0 && setting2 != 0 && strcmp (setting1, setting2))) - { - printf ("FAILED: crypt_gensalt defaulting to $2b$\n" - " $2b$ -> %s\n" -@@ -196,6 +226,7 @@ main (void) - free (setting2); - } - -+#if INCLUDE_bcrypt - /* FIXME: This test is a little too specific. It used to be in - test-bcrypt.c and I'm not sure what it's meant to be testing. */ - { -@@ -225,6 +256,6 @@ main (void) - free (setting1); - free (setting2); - } -- -+#endif - return status; - } - -From 15b30b6d7da6d5470de65f9a2a4d676f82423ceb Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Wed, 4 Jul 2018 22:31:02 -0400 -Subject: [PATCH 16/41] .travis.yml: Use --enable-hashes instead of - --enable-weak-hashes. - ---- - .travis.yml | 26 +++++++++++++------------- - 1 file changed, 13 insertions(+), 13 deletions(-) - -diff --git a/.travis.yml b/.travis.yml -index 7e892b2..ffca408 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -19,80 +19,80 @@ matrix: - os: linux - services: docker - env: -- - CONF="--enable-obsolete-api --enable-weak-hashes" -+ - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" - - CODECOV=1 - - compiler: gcc - os: linux - services: docker - env: -- - CONF="--enable-obsolete-api --enable-weak-hashes" -+ - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" - - compiler: clang - os: linux - services: docker - env: -- - CONF="--enable-obsolete-api --enable-weak-hashes" -+ - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" - - compiler: gcc - os: linux - services: docker - env: -- - CONF="--enable-obsolete-api --enable-weak-hashes" -+ - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="latest" - - compiler: clang - os: linux - services: docker - env: -- - CONF="--enable-obsolete-api --enable-weak-hashes" -+ - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="latest" - - compiler: gcc - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --enable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" - - compiler: clang - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --enable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" - - compiler: gcc - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --enable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="latest" - - compiler: clang - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --enable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="latest" - - compiler: gcc - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --disable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="rawhide" - - compiler: clang - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --disable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="rawhide" - - compiler: gcc - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --disable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="latest" - - compiler: clang - os: linux - services: docker - env: -- - CONF="--disable-obsolete-api --disable-weak-hashes" -+ - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="latest" - - before_install: - -From a33d95ea613256c46f0b05fa2345080d47193c9e Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Wed, 4 Jul 2018 15:59:40 +0000 -Subject: [PATCH 17/41] .travis.yml: add --enable-hashes=glibc to the test - matrix - ---- - .travis.yml | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/.travis.yml b/.travis.yml -index ffca408..b8a7ecf 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -94,6 +94,30 @@ matrix: - env: - - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="latest" -+ - compiler: gcc -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api --enable-hashes=glibc" -+ - FCVER="rawhide" -+ - compiler: clang -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api --enable-hashes=glibc" -+ - FCVER="rawhide" -+ - compiler: gcc -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api --enable-hashes=glibc" -+ - FCVER="latest" -+ - compiler: clang -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api --enable-hashes=glibc" -+ - FCVER="latest" - - before_install: - - for i in `seq 0 99`; do docker pull fedora:$FCVER && i= && break || sleep 1; done; [ -z "$i" ] - -From a7f9df50cecec46bb8176382faa685ce35ca72be Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Thu, 5 Jul 2018 15:20:05 -0400 -Subject: [PATCH 18/41] Make salt validation pickier. - -This started out as a patch to fold together test-crypt-badsalt.c and -test-crypt-nonnull.c (which were almost the same program) and extend -their testing from DES to all of the supported hashes. That revealed -that many of the supported hash functions do not validate the contents -of their salt strings very carefully. - -This patch has a low but nonzero backward compatibility risk, because -now we reject certain calls to crypt*() that we would previously have -accepted. In particular, setting strings of the form - - $5$xxxxxxx*xxxxxxxx$ - -where x stands for any "itoa64" character and * for any non-"itoa64" -character, would formerly be accepted but are now rejected. Some of -the hash algorithms that were lenient about the contents of the salt -would echo back the salt verbatim, and others would convert it to the -base64 alphabet somehow. I think it's unlikely that this occurs in -real password files but I don't have a lot of data to base that on. ---- - .gitignore | 3 +- - .travis.yml | 2 +- - Makefile.am | 9 +- - alg-des-tables.c | 30 +++-- - crypt-des.c | 80 ++++++++--- - crypt-md5.c | 9 +- - crypt-pbkdf1-sha1.c | 37 +++--- - crypt-sha256.c | 11 +- - crypt-sha512.c | 11 +- - crypt-sunmd5.c | 72 +++++----- - crypt.c | 17 +-- - test-badsalt.c | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++ - test-crypt-badsalt.c | 139 ------------------- - test-crypt-nonnull.c | 97 -------------- - test-gensalt.c | 31 +++-- - 15 files changed, 558 insertions(+), 357 deletions(-) - create mode 100644 test-badsalt.c - delete mode 100644 test-crypt-badsalt.c - delete mode 100644 test-crypt-nonnull.c - -diff --git a/.gitignore b/.gitignore -index 9f443bd..bb7f15c 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -53,13 +53,12 @@ - /test-alg-sha1 - /test-alg-sha256 - /test-alg-sha512 -+/test-badsalt - /test-bigcrypt - /test-byteorder --/test-crypt-badsalt - /test-crypt-bcrypt - /test-crypt-des - /test-crypt-md5 --/test-crypt-nonnull - /test-crypt-nthash - /test-crypt-pbkdf1-sha1 - /test-crypt-sha256 -diff --git a/.travis.yml b/.travis.yml -index b8a7ecf..31c50fa 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -156,4 +156,4 @@ script: - - docker exec -t buildenv /bin/sh -c "(make -C /opt/libxcrypt -j$((`nproc --all` * 2)) check || (cat /opt/libxcrypt/test-suite.log && exit 1))" - - after_success: -- - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "cd /opt/libxcrypt ; lcov --directory . --capture --output-file all_coverage.info ; lcov --remove all_coverage.info '/usr/*' '*test*' > coverage.info ; rm -f all_coverage.info ; codecov -X gcov" ; fi -+ - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "make -C /opt/libxcrypt check && cd /opt/libxcrypt && lcov --directory . --capture --output-file all_coverage.info && lcov --remove all_coverage.info '/usr/*' '*test*' > coverage.info && rm all_coverage.info && codecov -X gcov" ; fi -diff --git a/Makefile.am b/Makefile.am -index 040d719..79d59d7 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -122,11 +122,11 @@ endif - check_PROGRAMS = \ - test-alg-des test-alg-hmac-sha1 test-alg-md4 test-alg-md5 \ - test-alg-sha1 test-alg-sha256 test-alg-sha512 \ -- test-crypt-badsalt test-crypt-bcrypt test-crypt-des \ -- test-crypt-md5 test-crypt-nonnull test-crypt-nthash \ -+ test-crypt-bcrypt test-crypt-des \ -+ test-crypt-md5 test-crypt-nthash \ - test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \ - test-crypt-sunmd5 \ -- test-byteorder test-gensalt -+ test-byteorder test-badsalt test-gensalt - - if ENABLE_OBSOLETE_API - libcrypt_la_SOURCES += crypt-des-obsolete.c -@@ -157,16 +157,15 @@ LOG_COMPILER = m4/skip-if-exec-format-error - endif - EXTRA_DIST += m4/skip-if-exec-format-error - --test_crypt_badsalt_LDADD = libcrypt.la - test_crypt_bcrypt_LDADD = libcrypt.la - test_crypt_des_LDADD = libcrypt.la - test_crypt_md5_LDADD = libcrypt.la --test_crypt_nonnull_LDADD = libcrypt.la - test_crypt_nthash_LDADD = libcrypt.la - test_crypt_pbkdf1_sha1_LDADD = libcrypt.la - test_crypt_sha256_LDADD = libcrypt.la - test_crypt_sha512_LDADD = libcrypt.la - test_crypt_sunmd5_LDADD = libcrypt.la -+test_badsalt_LDADD = libcrypt.la - test_gensalt_LDADD = libcrypt.la - test_des_obsolete_LDADD = libcrypt.la - test_des_obsolete_r_LDADD = libcrypt.la -diff --git a/alg-des-tables.c b/alg-des-tables.c -index c46d1c4..4204a37 100644 ---- a/alg-des-tables.c -+++ b/alg-des-tables.c -@@ -51,7 +51,8 @@ - - #if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big - --const uint8_t m_sbox[4][4096] = { -+const uint8_t m_sbox[4][4096] = -+{ - { - 0xef, 0xe3, 0xe1, 0xed, 0xe8, 0xe4, 0xee, 0xe7, 0xe6, 0xef, 0xeb, 0xe2, - 0xe3, 0xe8, 0xe4, 0xee, 0xe9, 0xec, 0xe7, 0xe0, 0xe2, 0xe1, 0xed, 0xea, -@@ -1430,7 +1431,8 @@ const uint8_t m_sbox[4][4096] = { - }, - }; - --const uint32_t ip_maskl[8][256] = { -+const uint32_t ip_maskl[8][256] = -+{ - { - 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00000100, 0x00000101, 0x00000000, 0x00000001, 0x00000000, 0x00000001, -@@ -1793,7 +1795,8 @@ const uint32_t ip_maskl[8][256] = { - }, - }; - --const uint32_t ip_maskr[8][256] = { -+const uint32_t ip_maskr[8][256] = -+{ - { - 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, - 0x00000001, 0x00000001, 0x00000100, 0x00000100, 0x00000101, 0x00000101, -@@ -2156,7 +2159,8 @@ const uint32_t ip_maskr[8][256] = { - }, - }; - --const uint32_t fp_maskl[8][256] = { -+const uint32_t fp_maskl[8][256] = -+{ - { - 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, - 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, -@@ -2519,7 +2523,8 @@ const uint32_t fp_maskl[8][256] = { - }, - }; - --const uint32_t fp_maskr[8][256] = { -+const uint32_t fp_maskr[8][256] = -+{ - { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -@@ -2882,7 +2887,8 @@ const uint32_t fp_maskr[8][256] = { - }, - }; - --const uint32_t key_perm_maskl[8][128] = { -+const uint32_t key_perm_maskl[8][128] = -+{ - { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -@@ -3077,7 +3083,8 @@ const uint32_t key_perm_maskl[8][128] = { - }, - }; - --const uint32_t key_perm_maskr[8][128] = { -+const uint32_t key_perm_maskr[8][128] = -+{ - { - 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010, - 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001, -@@ -3272,7 +3279,8 @@ const uint32_t key_perm_maskr[8][128] = { - }, - }; - --const uint32_t comp_maskl[8][128] = { -+const uint32_t comp_maskl[8][128] = -+{ - { - 0x00000000, 0x00000010, 0x00004000, 0x00004010, 0x00040000, 0x00040010, - 0x00044000, 0x00044010, 0x00000100, 0x00000110, 0x00004100, 0x00004110, -@@ -3467,7 +3475,8 @@ const uint32_t comp_maskl[8][128] = { - }, - }; - --const uint32_t comp_maskr[8][128] = { -+const uint32_t comp_maskr[8][128] = -+{ - { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -@@ -3662,7 +3671,8 @@ const uint32_t comp_maskr[8][128] = { - }, - }; - --const uint32_t psbox[4][256] = { -+const uint32_t psbox[4][256] = -+{ - { - 0x00000000, 0x00004000, 0x40000000, 0x40004000, 0x00000010, 0x00004010, - 0x40000010, 0x40004010, 0x00080000, 0x00084000, 0x40080000, 0x40084000, -diff --git a/crypt-des.c b/crypt-des.c -index 3d8bc2e..b197dcd 100644 ---- a/crypt-des.c -+++ b/crypt-des.c -@@ -80,22 +80,22 @@ static const uint8_t ascii64[] = - /* 0000000000111111111122222222223333333333444444444455555555556666 */ - /* 0123456789012345678901234567890123456789012345678901234567890123 */ - --static inline unsigned int -+static inline int - ascii_to_bin(char ch) - { - if (ch > 'z') -- return 0; -+ return -1; - if (ch >= 'a') -- return (unsigned int)(ch - 'a' + 38); -+ return ch - 'a' + 38; - if (ch > 'Z') -- return 0; -+ return -1; - if (ch >= 'A') -- return (unsigned int)(ch - 'A' + 12); -+ return ch - 'A' + 12; - if (ch > '9') -- return 0; -+ return -1; - if (ch >= '.') -- return (unsigned int)(ch - '.'); -- return 0; -+ return ch - '.'; -+ return -1; - } - - /* Generate an 11-character DES password hash into the buffer at -@@ -169,10 +169,21 @@ crypt_des_rn (const char *phrase, const char *setting, - - /* "old"-style: setting - 2 bytes of salt, phrase - up to 8 characters. - Note: ascii_to_bin maps all byte values outside the ascii64 -- alphabet to zero. Do not read past the end of the string. */ -- salt = ascii_to_bin (setting[0]); -- if (setting[0]) -- salt |= ascii_to_bin (setting[1]) << 6; -+ alphabet to -1. Do not read past the end of the string. */ -+ i = ascii_to_bin (setting[0]); -+ if (i < 0) -+ { -+ errno = EINVAL; -+ return; -+ } -+ salt = (unsigned int)i; -+ i = ascii_to_bin (setting[1]); -+ if (i < 0) -+ { -+ errno = EINVAL; -+ return; -+ } -+ salt |= ((unsigned int)i << 6); - - /* Write the canonical form of the salt to the output buffer. We do - this instead of copying from the setting because the setting -@@ -247,9 +258,20 @@ crypt_des_big_rn (const char *phrase, const char *setting, - - /* The setting string is exactly the same as for a traditional DES - hash. */ -- salt = ascii_to_bin (setting[0]); -- if (setting[0]) -- salt |= ascii_to_bin (setting[1]) << 6; -+ i = ascii_to_bin (setting[0]); -+ if (i < 0) -+ { -+ errno = EINVAL; -+ return; -+ } -+ salt = (unsigned int)i; -+ i = ascii_to_bin (setting[1]); -+ if (i < 0) -+ { -+ errno = EINVAL; -+ return; -+ } -+ salt |= ((unsigned int)i << 6); - - *cp++ = ascii64[salt & 0x3f]; - *cp++ = ascii64[(salt >> 6) & 0x3f]; -@@ -272,9 +294,9 @@ crypt_des_big_rn (const char *phrase, const char *setting, - break; - - /* change the salt (1st 2 chars of previous block) - this was found -- by dowsing */ -- salt = ascii_to_bin ((char)cp[0]); -- salt |= ascii_to_bin ((char)cp[1]) << 6; -+ by dowsing - no need to check for invalid characters here */ -+ salt = (unsigned int)ascii_to_bin ((char)cp[0]); -+ salt |= (unsigned int)ascii_to_bin ((char)cp[1]) << 6; - cp += 11; - } - } -@@ -309,17 +331,33 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting, - uint32_t count = 0, salt = 0; - uint8_t *keybuf = buf->keybuf, *pkbuf = buf->pkbuf; - uint8_t *cp = output; -- int i; -+ int i, x; - - /* "new"-style DES hash: - setting - underscore, 4 bytes of count, 4 bytes of salt - phrase - unlimited characters - */ - for (i = 1; i < 5; i++) -- count |= ascii_to_bin(setting[i]) << ((i - 1) * 6); -+ { -+ x = ascii_to_bin(setting[i]); -+ if (x < 0) -+ { -+ errno = EINVAL; -+ return; -+ } -+ count |= (unsigned int)x << ((i - 1) * 6); -+ } - - for (i = 5; i < 9; i++) -- salt |= ascii_to_bin(setting[i]) << ((i - 5) * 6); -+ { -+ x = ascii_to_bin(setting[i]); -+ if (x < 0) -+ { -+ errno = EINVAL; -+ return; -+ } -+ salt |= (unsigned int)x << ((i - 5) * 6); -+ } - - memcpy (cp, setting, 9); - cp += 9; -diff --git a/crypt-md5.c b/crypt-md5.c -index 1a9139a..f051794 100644 ---- a/crypt-md5.c -+++ b/crypt-md5.c -@@ -31,7 +31,7 @@ - static const char md5_salt_prefix[] = "$1$"; - - /* Table with characters for base64 transformation. */ --static const char b64t[64] = -+static const char b64t[] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - /* The maximum length of an MD5 salt string (just the actual salt, not -@@ -88,7 +88,12 @@ crypt_md5_rn (const char *phrase, const char *setting, - /* Skip salt prefix. */ - salt += sizeof (md5_salt_prefix) - 1; - -- salt_len = strcspn (salt, "$"); -+ salt_len = strspn (salt, b64t); -+ if (salt[salt_len] && salt[salt_len] != '$') -+ { -+ errno = EINVAL; -+ return; -+ } - if (salt_len > SALT_LEN_MAX) - salt_len = SALT_LEN_MAX; - phrase_len = strlen (phrase); -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index 544d890..6bacc21 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -148,30 +148,33 @@ crypt_sha1_rn (const char *phrase, const char *setting, - /* - * Salt format is - * $$$salt[$] -- * If it does not start with $ we use our default iterations. - */ - -- /* If it starts with the magic string, then skip that */ -- if (!strncmp (setting, magic, strlen (magic))) -+ /* If the string doesn't starts with the magic prefix, we shouldn't have been called */ -+ if (strncmp (setting, magic, strlen (magic))) - { -- setting += strlen (magic); -- /* and get the iteration count */ -- iterations = (unsigned long)strtoul (setting, (char **)&ep, 10); -- if (*ep != '$') -- { -- errno = EINVAL; -- return; /* invalid input */ -- } -- setting = (char *)ep + 1; /* skip over the '$' */ -+ errno = EINVAL; -+ return; - } -- else -+ -+ setting += strlen (magic); -+ /* get the iteration count */ -+ iterations = (unsigned long)strtoul (setting, (char **)&ep, 10); -+ if (*ep != '$') - { -- iterations = (unsigned long)crypt_sha1_iterations (0); -+ errno = EINVAL; -+ return; /* invalid input */ - } -+ setting = (char *)ep + 1; /* skip over the '$' */ - -- /* It stops at the next '$', max CRYPT_SHA1_ITERATIONS chars */ -- for (sp = setting; *sp && *sp != '$' && sp < (setting + CRYPT_SHA1_ITERATIONS); sp++) -- continue; -+ /* The next 1..CRYPT_SHA1_SALT_LENGTH bytes should be itoa64 characters, -+ followed by another '$' (or end of string). */ -+ sp = setting + strspn (setting, (const char *)itoa64); -+ if (sp == setting || (*sp && *sp != '$')) -+ { -+ errno = EINVAL; -+ return; -+ } - - /* Get the length of the actual salt */ - sl = (size_t)(sp - setting); -diff --git a/crypt-sha256.c b/crypt-sha256.c -index 8b4ba67..b8640b8 100644 ---- a/crypt-sha256.c -+++ b/crypt-sha256.c -@@ -70,7 +70,7 @@ static_assert (sizeof (struct sha256_buffer) <= ALG_SPECIFIC_SIZE, - - - /* Table with characters for base64 transformation. */ --static const char b64t[64] = -+static const char b64t[] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - /* Subroutine of _xcrypt_crypt_sha256_rn: Feed CTX with LEN bytes of a -@@ -133,7 +133,14 @@ crypt_sha256_rn (const char *phrase, const char *setting, - } - } - -- salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX); -+ salt_len = strspn (salt, b64t); -+ if (salt[salt_len] && salt[salt_len] != '$') -+ { -+ errno = EINVAL; -+ return; -+ } -+ if (salt_len > SALT_LEN_MAX) -+ salt_len = SALT_LEN_MAX; - phrase_len = strlen (phrase); - - /* Compute alternate SHA256 sum with input PHRASE, SALT, and PHRASE. The -diff --git a/crypt-sha512.c b/crypt-sha512.c -index 28e4f1c..1a651e0 100644 ---- a/crypt-sha512.c -+++ b/crypt-sha512.c -@@ -70,7 +70,7 @@ static_assert (sizeof (struct sha512_buffer) <= ALG_SPECIFIC_SIZE, - - - /* Table with characters for base64 transformation. */ --static const char b64t[64] = -+static const char b64t[] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - /* Subroutine of _xcrypt_crypt_sha512_rn: Feed CTX with LEN bytes of a -@@ -133,7 +133,14 @@ crypt_sha512_rn (const char *phrase, const char *setting, - } - } - -- salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX); -+ salt_len = strspn (salt, b64t); -+ if (salt[salt_len] && salt[salt_len] != '$') -+ { -+ errno = EINVAL; -+ return; -+ } -+ if (salt_len > SALT_LEN_MAX) -+ salt_len = SALT_LEN_MAX; - phrase_len = strlen (phrase); - - /* Compute alternate SHA512 sum with input PHRASE, SALT, and PHRASE. The -diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c -index fcd3984..f3c84a8 100644 ---- a/crypt-sunmd5.c -+++ b/crypt-sunmd5.c -@@ -115,41 +115,51 @@ to64 (char *s, uint64_t v, int n) - } - } - --#define ROUNDS "rounds=" -+#define ROUNDS ",rounds=" - #define ROUNDSLEN (sizeof (ROUNDS) - 1) - - /* -- * get the integer value after rounds= where ever it occurs in the string. -- * if the last char after the int is a , or $ that is fine anything else is an -- * error. -+ * get the integer value after ,rounds= if present -+ * s should point immediately after $md5 -+ * set *puresalt one character after the dollar sign after -+ * the number of rounds (if present) or to NULL if the syntax -+ * is invalid - */ - static uint32_t --getrounds (const char *s) -+getrounds (const char *s, const char **puresalt) - { -- char *r, *p, *e; -+ const char *p; -+ char *e; - long val; - -+ *puresalt = 0; -+ - if (s == NULL) - return (0); - -- if ((r = strstr (s, ROUNDS)) == NULL) -- return (0); -+ if (*s == '$') -+ { -+ *puresalt = s + 1; -+ return (0); -+ } - -- if (strncmp (r, ROUNDS, ROUNDSLEN) != 0) -+ if (strncmp (s, ROUNDS, ROUNDSLEN) != 0) - return (0); - -- p = r + ROUNDSLEN; -+ p = s + ROUNDSLEN; - errno = 0; - val = strtol (p, &e, 10); - /* - * An error occured or there is non-numeric stuff at the end - * which isn't one of the crypt(3c) special chars ',' or '$' - */ -- if (errno != 0 || val < 0 || -- !(*e == '\0' || *e == ',' || *e == '$')) -- { -- return (0); -- } -+ if (errno != 0 || val < 0 || p == e || (*e != '\0' && *e != '$')) -+ return (0); -+ -+ if (*e == '$') -+ *puresalt = e + 1; -+ else -+ *puresalt = e; - - return ((uint32_t)val); - } -@@ -189,7 +199,7 @@ gensalt_sunmd5_rn (unsigned long count, - /* Generated salt is at least 27 bytes - and a maximum of 32 bytes long. */ - snprintf ((char *)output, o_size, -- "$" CRYPT_ALGNAME "," ROUNDS "%u$%s$", -+ "$" CRYPT_ALGNAME ROUNDS "%u$%s$", - (unsigned int)count, rndstr); - } - -@@ -245,22 +255,27 @@ crypt_sunmd5_rn (const char *phrase, const char *setting, - int round; - uint32_t maxrounds = BASIC_ROUND_COUNT; - uint32_t l; -- char *puresalt; -- char *saltend; -- char *p; -+ const char *ps = 0; -+ const char *saltend = 0; -+ char *p, *puresalt; - struct sunmd5_ctx *data = scratch; - - /* -- * Extract the puresalt (if it exists) from the existing salt string -+ * Extract the rounds (if it exists) and puresalt from the salt string - * $md5[,rounds=%d]$$ - */ -- saltend = strrchr (setting, '$'); -- -- if (saltend == NULL || saltend == setting) -+ maxrounds += getrounds (setting + sizeof ("$" CRYPT_ALGNAME) - 1, &ps); -+ if (ps) -+ saltend = ps + strspn (ps, (char *)itoa64); -+ if (!saltend || saltend == ps || saltend[0] != '$') - { - errno = EINVAL; - return; - } -+ /* For bug-compatibility with the original implementation, if saltend -+ points at "$$", advance it to point at the second dollar sign. */ -+ if (saltend[0] == '$' && saltend[1] == '$') -+ saltend += 1; - - if (saltend[1] != '\0') - { -@@ -289,17 +304,6 @@ crypt_sunmd5_rn (const char *phrase, const char *setting, - } - } - -- /* There must not be any dollar sign '$', but -- the last character before the terminating -- '\0' in the string containing the salt. */ -- if (puresalt[strlen (puresalt) - 2] == '$') -- { -- errno = EINVAL; -- return; -- } -- -- maxrounds += getrounds (setting); -- - /* initialise the context */ - md5_init_ctx (&(data->context)); - -diff --git a/crypt.c b/crypt.c -index e1bfc5b..387b69a 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -83,17 +83,6 @@ static const struct hashfn hash_algorithms[] = - HASH_ALGORITHM_TABLE_ENTRIES - }; - --#if INCLUDE_des || INCLUDE_des_big --static int --is_des_salt_char (char c) --{ -- return ((c >= 'a' && c <= 'z') || -- (c >= 'A' && c <= 'Z') || -- (c >= '0' && c <= '9') || -- c == '.' || c == '/'); --} --#endif -- - static const struct hashfn * - get_hashfn (const char *setting) - { -@@ -109,7 +98,7 @@ get_hashfn (const char *setting) - else - { - if (setting[0] == '\0' || -- (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1]))) -+ (setting[0] != '$' && setting[0] != '*')) - return h; - } - #endif -@@ -265,8 +254,8 @@ do_crypt (const char *phrase, const char *setting, struct crypt_data *data) - } - #else - h->crypt (phrase, setting, -- (unsigned char *)data->output, sizeof data->output, -- cint->alg_specific, sizeof cint->alg_specific); -+ (unsigned char *)data->output, sizeof data->output, -+ cint->alg_specific, sizeof cint->alg_specific); - #endif - } - -diff --git a/test-badsalt.c b/test-badsalt.c -new file mode 100644 -index 0000000..41d164a ---- /dev/null -+++ b/test-badsalt.c -@@ -0,0 +1,367 @@ -+/* Test rejection of ill-formed password hashes. -+ Copyright (C) 2012-2018 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#include "crypt-port.h" -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const char phrase[] = "values of β will give rise to dom!"; -+ -+struct testcase -+{ -+ const char *label; -+ size_t plen; -+ const char *setting; -+}; -+static const struct testcase testcases[] = -+{ -+ /* These strings are invalid regardless of the algorithm. */ -+ { "*too short", 1, "/" }, -+ { "*invalid char :", 1, ":" }, -+ { "*invalid char ;", 1, ";" }, -+ { "*invalid char *", 1, "*" }, -+ { "*invalid char !", 1, "!" }, -+ { "*invalid char \\", 1, "\\" }, -+ { "*invalid white 1", 1, " " }, -+ { "*invalid white 2", 1, "\t" }, -+ { "*invalid white 3", 1, "\r" }, -+ { "*invalid white 4", 1, "\n" }, -+ { "*invalid white 5", 1, "\f" }, -+ { "*invalid ctrl 1", 1, "\1" }, -+ { "*invalid ctrl 2", 1, "\177" }, -+ { "*failure token 1", 2, "*0" }, -+ { "*failure token 2", 2, "*1" }, -+ -+ /* Each of these is a valid setting string for some algorithm, -+ from which we will derive many invalid setting strings. -+ This is an expensive test, so where possible, the number of -+ "rounds" of the hash function has been set abnormally low. */ -+#if INCLUDE_des -+ { "DES (trad.)", 2, "Mp" }, -+ { "*DES (trad.), 1st char invalid -", 2, "-p" }, -+ { "*DES (trad.), 2nd char invalid -", 2, "M-" }, -+ { "*DES (trad.), 1st char invalid :", 2, ":p" }, -+ { "*DES (trad.), 2nd char invalid :", 2, "M:" }, -+ { "*DES (trad.), 1st char invalid [", 2, "[p" }, -+ { "*DES (trad.), 2nd char invalid [", 2, "M[" }, -+ { "*DES (trad.), 1st char invalid {", 2, "{p" }, -+ { "*DES (trad.), 2nd char invalid {", 2, "M{" }, -+#endif -+#if INCLUDE_des_big -+ { "DES (bigcrypt)", 2, "Mp............" }, -+ { "*DES (bigcrypt), 1st char invalid -", 2, "-p............" }, -+ { "*DES (bigcrypt), 2nd char invalid -", 2, "M-............" }, -+ { "*DES (bigcrypt), 1st char invalid :", 2, ":p............" }, -+ { "*DES (bigcrypt), 2nd char invalid :", 2, "M:............" }, -+ { "*DES (bigcrypt), 1st char invalid [", 2, "[p............" }, -+ { "*DES (bigcrypt), 2nd char invalid [", 2, "M[............" }, -+ { "*DES (bigcrypt), 1st char invalid {", 2, "{p............" }, -+ { "*DES (bigcrypt), 2nd char invalid {", 2, "M{............" }, -+#endif -+#if INCLUDE_des_xbsd -+ { "DES (BSDi)", 9, "_J9..MJHn" }, -+ { "*DES (BSDi), 1st char invalid -", 9, "_-9..MJHn" }, -+ { "*DES (BSDi), 2nd char invalid -", 9, "_J-..MJHn" }, -+ { "*DES (BSDi), 3rd char invalid -", 9, "_J9-.MJHn" }, -+ { "*DES (BSDi), 4th char invalid -", 9, "_J9.-MJHn" }, -+ { "*DES (BSDi), 5th char invalid -", 9, "_J9..-JHn" }, -+ { "*DES (BSDi), 6th char invalid -", 9, "_J9..M-Hn" }, -+ { "*DES (BSDi), 7th char invalid -", 9, "_J9..MJ-n" }, -+ { "*DES (BSDi), 8th char invalid -", 9, "_J9..MJH-" }, -+ { "*DES (BSDi), 1st char invalid :", 9, "_:9..MJHn" }, -+ { "*DES (BSDi), 2nd char invalid :", 9, "_J:..MJHn" }, -+ { "*DES (BSDi), 3rd char invalid :", 9, "_J9:.MJHn" }, -+ { "*DES (BSDi), 4th char invalid :", 9, "_J9.:MJHn" }, -+ { "*DES (BSDi), 5th char invalid :", 9, "_J9..:JHn" }, -+ { "*DES (BSDi), 6th char invalid :", 9, "_J9..M:Hn" }, -+ { "*DES (BSDi), 7th char invalid :", 9, "_J9..MJ:n" }, -+ { "*DES (BSDi), 8th char invalid :", 9, "_J9..MJH:" }, -+ { "*DES (BSDi), 1st char invalid [", 9, "_[9..MJHn" }, -+ { "*DES (BSDi), 2nd char invalid [", 9, "_J[..MJHn" }, -+ { "*DES (BSDi), 3rd char invalid [", 9, "_J9[.MJHn" }, -+ { "*DES (BSDi), 4th char invalid [", 9, "_J9.[MJHn" }, -+ { "*DES (BSDi), 5th char invalid [", 9, "_J9..[JHn" }, -+ { "*DES (BSDi), 6th char invalid [", 9, "_J9..M[Hn" }, -+ { "*DES (BSDi), 7th char invalid [", 9, "_J9..MJ[n" }, -+ { "*DES (BSDi), 8th char invalid [", 9, "_J9..MJH[" }, -+ { "*DES (BSDi), 1st char invalid {", 9, "_{9..MJHn" }, -+ { "*DES (BSDi), 2nd char invalid {", 9, "_J{..MJHn" }, -+ { "*DES (BSDi), 3rd char invalid {", 9, "_J9{.MJHn" }, -+ { "*DES (BSDi), 4th char invalid {", 9, "_J9.{MJHn" }, -+ { "*DES (BSDi), 5th char invalid {", 9, "_J9..{JHn" }, -+ { "*DES (BSDi), 6th char invalid {", 9, "_J9..M{Hn" }, -+ { "*DES (BSDi), 7th char invalid {", 9, "_J9..MJ{n" }, -+ { "*DES (BSDi), 8th char invalid {", 9, "_J9..MJH{" }, -+#endif -+#if INCLUDE_md5 -+ { "MD5 (FreeBSD)", 12, "$1$MJHnaAke$" }, -+#endif -+#if INCLUDE_sunmd5 -+ { "MD5 (Sun, plain)", 14, "$md5$1xMeE.at$" }, -+ { "MD5 (Sun, rounds)", 25, "$md5,rounds=123$1xMeE.at$" }, -+#endif -+#if INCLUDE_nthash -+ { "NTHASH (bare)", 3, "$3$" }, -+ { "NTHASH (fake salt)", 3, "$3$__not_used__c809a450df09a3" }, -+#endif -+#if INCLUDE_sha1 -+ { "HMAC-SHA1", 27, "$sha1$123$GGXpNqoJvglVTkGU$" }, -+#endif -+#if INCLUDE_sha256 -+ { "SHA-256 (plain)", 20, "$5$MJHnaAkegEVYHsFK$" }, -+ { "SHA-256 (rounds)", 32, "$5$rounds=1000$MJHnaAkegEVYHsFK$" }, -+#endif -+#if INCLUDE_sha512 -+ { "SHA-512 (plain)", 20, "$6$MJHnaAkegEVYHsFK$" }, -+ { "SHA-512 (rounds)", 32, "$6$rounds=1000$MJHnaAkegEVYHsFK$" }, -+#endif -+#if INCLUDE_bcrypt -+ { "bcrypt (a04)", 29, "$2a$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "bcrypt (b04)", 29, "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "bcrypt (x04)", 29, "$2x$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "bcrypt (y04)", 29, "$2y$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+#endif -+}; -+ -+static bool -+check_results (const char *label, const char *fn, -+ const char *retval, const char *setting, -+ bool expected_to_succeed) -+{ -+ size_t l_setting = strlen (setting); -+ if (expected_to_succeed) -+ { -+ if (retval[0] == '*' || -+ strncmp (retval, setting, -+ (setting[l_setting - 1] == '*') ? l_setting - 1 : l_setting)) -+ { -+ printf ("FAIL: %s/%s/%s: expected success, got non-matching %s\n", -+ label, setting, fn, retval); -+ return false; -+ } -+ } -+ else -+ { -+ if (retval[0] != '*' || -+ (l_setting >= 2 && !strncmp (retval, setting, l_setting))) -+ { -+ printf ("FAIL: %s/%s/%s: expected failure, got %s\n", -+ label, setting, fn, retval); -+ return false; -+ } -+ } -+ return true; -+} -+ -+static bool -+check_crypt (const char *label, const char *fn, -+ const char *retval, const char *setting, -+ bool expected_to_succeed) -+{ -+ /* crypt/crypt_r should never return null */ -+ if (!retval) -+ { -+ printf ("FAIL: %s/%s/%s: returned NULL\n", label, setting, fn); -+ return false; -+ } -+ if (!check_results (label, fn, retval, setting, -+ expected_to_succeed)) -+ return false; -+ return true; -+} -+ -+static bool -+check_crypt_rn (const char *label, const char *fn, -+ const char *retval, const char *output, -+ const char *setting, bool expected_to_succeed) -+{ -+ bool ok = true; -+ if (expected_to_succeed) -+ { -+ if (!retval) -+ { -+ printf ("FAIL: %s/%s/%s: returned NULL\n", label, setting, fn); -+ ok = false; -+ } -+ else if (retval != output) -+ { -+ printf ("FAIL: %s/%s/%s: returned %p but output is %p\n", -+ label, setting, fn, -+ (const void *)retval, (const void *)output); -+ ok = false; -+ } -+ } -+ else -+ { -+ if (retval) -+ { -+ printf ("FAIL: %s/%s/%s: returned %p (output is %p), " -+ "should be NULL\n", -+ label, setting, fn, -+ (const void *)retval, (const void *)output); -+ ok = false; -+ } -+ } -+ if (!check_results (label, fn, output, setting, -+ expected_to_succeed)) -+ ok = false; -+ return ok; -+} -+ -+static bool -+test_one_setting (const char *label, const char *setting, -+ struct crypt_data *cd, bool expected_to_succeed) -+{ -+ bool ok = true; -+ const char *retval; -+ int cdsize = (int) sizeof (struct crypt_data); -+#ifdef VERBOSE -+ printf ("%s: testing %s (expect: %s)\n", label, setting, -+ expected_to_succeed ? "succeed" : "fail"); -+#endif -+ retval = crypt (phrase, setting); -+ if (!check_crypt (label, "crypt", retval, setting, expected_to_succeed)) -+ ok = false; -+ -+ retval = crypt_r (phrase, setting, cd); -+ if (!check_crypt (label, "crypt_r", retval, setting, expected_to_succeed)) -+ ok = false; -+ -+ retval = crypt_rn (phrase, setting, cd, cdsize); -+ if (!check_crypt_rn (label, "crypt_rn", retval, cd->output, -+ setting, expected_to_succeed)) -+ ok = false; -+ -+ retval = crypt_ra (phrase, setting, (void **)&cd, &cdsize); -+ if (!check_crypt_rn (label, "crypt_ra", retval, cd->output, -+ setting, expected_to_succeed)) -+ ok = false; -+ return ok; -+} -+ -+static bool -+test_one_case (const struct testcase *t, -+ char *page, size_t pagesize, -+ struct crypt_data *cd) -+{ -+ memset (page, 'a', pagesize); -+ -+ size_t l_setting = strlen (t->setting); -+ assert (l_setting <= pagesize); -+ if (t->label[0] == '*') -+ { -+ /* Hashing with this setting is expected to fail already. -+ We still want to verify that we do not read past the end of -+ the string. */ -+ char *p = page + pagesize - (l_setting + 1); -+ memcpy (p, t->setting, l_setting + 1); -+ if (!test_one_setting (t->label + 1, p, cd, false)) -+ return false; -+ printf ("PASS: %s\n", t->label + 1); -+ return true; -+ } -+ else -+ { -+ /* Hashing with this setting is expected to succeed. */ -+ char goodhash[CRYPT_OUTPUT_SIZE]; -+ char *result = crypt_rn (phrase, t->setting, cd, -+ sizeof (struct crypt_data)); -+ if (!result) -+ { -+ printf ("FAIL: %s: initial hash returned NULL/%s (%s)\n", -+ t->label, cd->output, strerror (errno)); -+ return 1; -+ } -+ -+ size_t l_hash = strlen (result); -+ assert (l_hash + 1 <= CRYPT_OUTPUT_SIZE); -+ -+ memcpy (goodhash, result, l_hash + 1); -+ -+ char *p = page + pagesize - (l_hash + 1); -+ memcpy (p, goodhash, l_hash + 1); -+ -+ /* Rechecking the hash with the full output should succeed. */ -+ if (!test_one_setting (t->label, p, cd, true)) -+ return false; -+ -+ /* Recomputing the hash with its own prefix should produce a -+ hash with the same prefix. */ -+ p = page + pagesize - (t->plen + 1); -+ memcpy (p, goodhash, t->plen); -+ p[t->plen] = '\0'; -+ if (!test_one_setting (t->label, p, cd, true)) -+ return false; -+ -+ /* An invalid character after the prefix should not affect the -+ result of the hash computation. */ -+ p = page + pagesize - (t->plen + 2); -+ memcpy (p, goodhash, t->plen); -+ p[t->plen] = '*'; -+ p[t->plen+1] = '\0'; -+ if (!test_one_setting (t->label, p, cd, true)) -+ return false; -+ -+ /* However, an invalid character anywhere within the prefix should -+ cause hashing to fail. */ -+ for (size_t i = 1; i < t->plen; i++) -+ { -+ p = page + pagesize - (t->plen + 2 - i); -+ memcpy (p, goodhash, t->plen - i); -+ if (!test_one_setting (t->label, p, cd, false)) -+ return false; -+ } -+ printf ("PASS: %s\n", t->label); -+ return true; -+ } -+} -+ -+int -+main (void) -+{ -+ /* Set up a two-page region whose first page is read-write and -+ whose second page is inaccessible. */ -+ size_t pagesize = (size_t) sysconf (_SC_PAGESIZE); -+ char *page = mmap (0, pagesize * 2, PROT_READ|PROT_WRITE, -+ MAP_PRIVATE|MAP_ANON, -1, 0); -+ if (page == MAP_FAILED) -+ { -+ perror ("mmap"); -+ return 1; -+ } -+ memset (page, 'x', pagesize * 2); -+ if (mprotect (page + pagesize, pagesize, PROT_NONE)) -+ { -+ perror ("mprotect"); -+ return 1; -+ } -+ -+ struct crypt_data cd; -+ memset (&cd, 0, sizeof cd); -+ -+ bool ok = true; -+ for (size_t i = 0; i < ARRAY_SIZE (testcases); i++) -+ if (!test_one_case (&testcases[i], page, pagesize, &cd)) -+ ok = false; -+ -+ return ok ? 0 : 1; -+} -diff --git a/test-crypt-badsalt.c b/test-crypt-badsalt.c -deleted file mode 100644 -index 8ce7401..0000000 ---- a/test-crypt-badsalt.c -+++ /dev/null -@@ -1,139 +0,0 @@ --/* Test program for bad DES salt detection in crypt. -- Copyright (C) 2012-2017 Free Software Foundation, Inc. -- This file is part of the GNU C Library. -- -- The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- The GNU C Library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, see -- . */ -- --#include "crypt-port.h" --#include --#include --#include --#include --#include -- --static const char *tests[][3] = --{ --#if INCLUDE_des || INCLUDE_des_big -- { "no salt", "", "..ogcgXxFhnjI" /* valid setting */ }, --#endif -- { "single char", "/", "*0" /* invalid setting */ }, -- { "first char bad", "!x", "*0" /* invalid setting */ }, -- { "second char bad", "Z%", "*0" /* invalid setting */ }, -- { "both chars bad", ":@", "*0" /* invalid setting */ }, -- { "un$upported algorithm", "$2$", "*0" /* invalid setting */ }, -- { "un$upported $etting", "$2a$", "*0" /* invalid setting */ }, -- { "un$upported $etting", "$2b$", "*0" /* invalid setting */ }, -- { "un$upported $etting", "$2x$", "*0" /* invalid setting */ }, -- { "bad salt for BSDi", "_1", "*0" /* invalid setting */ }, -- { "end of page", NULL, "*0" /* invalid setting */ } --}; -- --int --main (void) --{ -- int cdsize = sizeof (struct crypt_data); -- int result = 0; -- struct crypt_data cd; -- struct crypt_data *cdptr = &cd; -- size_t n = ARRAY_SIZE (tests); -- size_t pagesize = (size_t) sysconf (_SC_PAGESIZE); -- char *page, *retval; -- const char *saltstr, *special = "%"; -- -- /* Check that crypt won't look at the second character if the first -- one is invalid. */ -- page = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE, -- MAP_PRIVATE | MAP_ANON, -1, 0); -- if (page == MAP_FAILED) -- { -- perror ("mmap"); -- n--; -- } -- else -- { -- if (mmap (page + pagesize, pagesize, 0, -- MAP_PRIVATE | MAP_ANON | MAP_FIXED, -- -1, 0) != page + pagesize) -- perror ("mmap 2"); -- page[pagesize - 1] = special[0]; -- tests[n - 1][1] = &page[pagesize - 1]; -- } -- -- /* Mark cd as initialized before first call to crypt_r. */ -- cd.initialized = 0; -- -- for (size_t i = 0; i < n; i++) -- { -- retval = crypt (tests[i][0], tests[i][1]); -- if (strcmp (tests[i][2], retval)) -- { -- result++; -- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0) -- saltstr = tests[i][1]; -- else -- saltstr = special; -- printf ("%s: crypt returned wrong magic value with salt \"%s\".\n", -- tests[i][0], saltstr); -- printf (" expected: \"%s\"\n got: \"%s\"\n\n", -- tests[i][2], retval); -- } -- -- retval = crypt_r (tests[i][0], tests[i][1], &cd); -- if (strcmp (tests[i][2], retval)) -- { -- result++; -- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0) -- saltstr = tests[i][1]; -- else -- saltstr = special; -- printf ("%s: crypt_r returned wrong magic value with salt \"%s\".\n", -- tests[i][0], saltstr); -- printf (" expected: \"%s\"\n got: \"%s\"\n\n", -- tests[i][2], retval); -- } -- -- crypt_rn (tests[i][0], tests[i][1], cdptr, cdsize); -- retval = cd.output; -- if (strcmp (tests[i][2], retval)) -- { -- result++; -- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0) -- saltstr = tests[i][1]; -- else -- saltstr = special; -- printf ("%s: crypt_rn returned wrong magic value with salt \"%s\".\n", -- tests[i][0], saltstr); -- printf (" expected: \"%s\"\n got: \"%s\"\n\n", -- tests[i][2], retval); -- } -- -- crypt_ra (tests[i][0], tests[i][1], (void **)&cdptr, &cdsize); -- retval = cd.output; -- if (strcmp (tests[i][2], retval)) -- { -- result++; -- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0) -- saltstr = tests[i][1]; -- else -- saltstr = special; -- printf ("%s: crypt_ra returned wrong magic value with salt \"%s\".\n", -- tests[i][0], saltstr); -- printf (" expected: \"%s\"\n got: \"%s\"\n\n", -- tests[i][2], retval); -- } -- } -- -- return result; --} -diff --git a/test-crypt-nonnull.c b/test-crypt-nonnull.c -deleted file mode 100644 -index e4738ff..0000000 ---- a/test-crypt-nonnull.c -+++ /dev/null -@@ -1,97 +0,0 @@ --/* Test program for bad DES salt detection in crypt. -- Copyright (C) 2012-2017 Free Software Foundation, Inc. -- This file is part of the GNU C Library. -- -- The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- The GNU C Library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, see -- . */ -- --#include "crypt-port.h" --#include --#include --#include --#include --#include -- --static const char *tests[][3] = --{ -- { "single char", "/" }, -- { "first char bad", "!x" }, -- { "second char bad", "Z%" }, -- { "both chars bad", ":@" }, -- { "un$upported algorithm", "$2$" }, -- { "un$upported $etting", "$2a$" }, -- { "un$upported $etting", "$2b$" }, -- { "un$upported $etting", "$2x$" }, -- { "bad salt for BSDi", "_1" }, -- { "end of page", NULL } --}; -- --int --main (void) --{ -- int cdsize = sizeof (struct crypt_data); -- int result = 0; -- struct crypt_data cd; -- struct crypt_data *cdptr = &cd; -- size_t n = ARRAY_SIZE (tests); -- size_t pagesize = (size_t) sysconf (_SC_PAGESIZE); -- char *page; -- const char *saltstr, *special = "%"; -- -- /* Check that crypt won't look at the second character if the first -- one is invalid. */ -- page = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE, -- MAP_PRIVATE | MAP_ANON, -1, 0); -- if (page == MAP_FAILED) -- { -- perror ("mmap"); -- n--; -- } -- else -- { -- if (mmap (page + pagesize, pagesize, 0, -- MAP_PRIVATE | MAP_ANON | MAP_FIXED, -- -1, 0) != page + pagesize) -- perror ("mmap 2"); -- page[pagesize - 1] = special[0]; -- tests[n - 1][1] = &page[pagesize - 1]; -- } -- -- for (size_t i = 0; i < n; i++) -- { -- if (crypt_rn (tests[i][0], tests[i][1], cdptr, cdsize)) -- { -- result++; -- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0) -- saltstr = tests[i][1]; -- else -- saltstr = special; -- printf ("%s: crypt_rn returned non-NULL with salt \"%s\"\n", -- tests[i][0], saltstr); -- } -- -- if (crypt_ra (tests[i][0], tests[i][1], (void **)&cdptr, &cdsize)) -- { -- result++; -- if (memcmp (&page[pagesize - 1], tests[i][1], 1) != 0) -- saltstr = tests[i][1]; -- else -- saltstr = special; -- printf ("%s: crypt_ra returned non-NULL with salt \"%s\"\n", -- tests[i][0], saltstr); -- } -- } -- -- return result; --} -diff --git a/test-gensalt.c b/test-gensalt.c -index b81fcf0..5b9d64c 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -18,7 +18,8 @@ static const char *const entropy[] = - static const char *const des_expected_output[] = { "Mp", "Pp", "ZH", "Uh"}; - #endif - #if INCLUDE_des_xbsd --static const char *const bsdi_expected_output[] = { -+static const char *const bsdi_expected_output[] = -+{ - "_J9..MJHn", - "_J9..PKXc", - "_J9..ZAFl", -@@ -26,7 +27,8 @@ static const char *const bsdi_expected_output[] = { - }; - #endif - #if INCLUDE_md5 --static const char *const md5_expected_output[] = { -+static const char *const md5_expected_output[] = -+{ - "$1$MJHnaAke", - "$1$PKXc3hCO", - "$1$ZAFlICwY", -@@ -34,7 +36,8 @@ static const char *const md5_expected_output[] = { - }; - #endif - #if INCLUDE_nthash --static const char *const nthash_expected_output[] = { -+static const char *const nthash_expected_output[] = -+{ - "$3$__not_used__c809a450df09a3", - "$3$__not_used__30d0d6f834c0c3", - "$3$__not_used__0eeeebb83d6fe4", -@@ -48,7 +51,8 @@ static const char *const nthash_expected_output[] = { - #define pbkdf_expected_output 0 /* output is not deterministic */ - #endif - #if INCLUDE_sha256 --static const char *const sha256_expected_output[] = { -+static const char *const sha256_expected_output[] = -+{ - "$5$MJHnaAkegEVYHsFK", - "$5$PKXc3hCOSyMqdaEQ", - "$5$ZAFlICwYRETzIzIj", -@@ -56,7 +60,8 @@ static const char *const sha256_expected_output[] = { - }; - #endif - #if INCLUDE_sha512 --static const char *const sha512_expected_output[] = { -+static const char *const sha512_expected_output[] = -+{ - "$6$MJHnaAkegEVYHsFK", - "$6$PKXc3hCOSyMqdaEQ", - "$6$ZAFlICwYRETzIzIj", -@@ -64,25 +69,29 @@ static const char *const sha512_expected_output[] = { - }; - #endif - #if INCLUDE_bcrypt --static const char *const bcrypt_a_expected_output[] = { -+static const char *const bcrypt_a_expected_output[] = -+{ - "$2a$05$UBVLHeMpJ/QQCv3XqJx8zO", - "$2a$05$kxUgPcrmlm9XoOjvxCyfP.", - "$2a$05$HPNDjKMRFdR7zC87CMSmA.", - "$2a$05$mAyzaIeJu41dWUkxEbn8hO" - }; --static const char *const bcrypt_b_expected_output[] = { -+static const char *const bcrypt_b_expected_output[] = -+{ - "$2b$05$UBVLHeMpJ/QQCv3XqJx8zO", - "$2b$05$kxUgPcrmlm9XoOjvxCyfP.", - "$2b$05$HPNDjKMRFdR7zC87CMSmA.", - "$2b$05$mAyzaIeJu41dWUkxEbn8hO" - }; --static const char *const bcrypt_x_expected_output[] = { -+static const char *const bcrypt_x_expected_output[] = -+{ - "$2x$05$UBVLHeMpJ/QQCv3XqJx8zO", - "$2x$05$kxUgPcrmlm9XoOjvxCyfP.", - "$2x$05$HPNDjKMRFdR7zC87CMSmA.", - "$2x$05$mAyzaIeJu41dWUkxEbn8hO" - }; --static const char *const bcrypt_y_expected_output[] = { -+static const char *const bcrypt_y_expected_output[] = -+{ - "$2y$05$UBVLHeMpJ/QQCv3XqJx8zO", - "$2y$05$kxUgPcrmlm9XoOjvxCyfP.", - "$2y$05$HPNDjKMRFdR7zC87CMSmA.", -@@ -167,8 +176,8 @@ main (void) - } - size_t slen = strlen (salt); - unsigned int expected_len = -- (!entropy[ent] && tcase->expected_auto_len) ? -- tcase->expected_auto_len : tcase->expected_len; -+ (!entropy[ent] && tcase->expected_auto_len) ? -+ tcase->expected_auto_len : tcase->expected_len; - if (slen != expected_len) - { - fprintf (stderr, - -From 58ac83090e107aa628a5be252931a2b8b0f286cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sun, 8 Jul 2018 23:59:53 +0200 -Subject: [PATCH 19/41] Fix Werror=stringop-truncation - ---- - test-gensalt.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/test-gensalt.c b/test-gensalt.c -index 5b9d64c..c08627e 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -208,9 +208,8 @@ main (void) - fprintf (stderr, " ok: %s/%u -> %s\n", - tcase->prefix, ent, salt); - -- /* Note: strncpy's somewhat odd fill-to-size-with-NULs behavior -- is specifically wanted in this case. */ -- strncpy (prev_output, salt, CRYPT_GENSALT_OUTPUT_SIZE); -+ XCRYPT_SECURE_MEMSET (prev_output, CRYPT_GENSALT_OUTPUT_SIZE); -+ strncpy (prev_output, salt, CRYPT_GENSALT_OUTPUT_SIZE -1 ); - } - } - - -From 98043c5be0ed8a09dfd49ad04b179c017ac78677 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 9 Jul 2018 00:49:19 +0200 -Subject: [PATCH 20/41] Fix DNF config for DNF v3.x - ---- - .travis.dnf.conf.rawhide_latest | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/.travis.dnf.conf.rawhide_latest b/.travis.dnf.conf.rawhide_latest -index ee4370a..52b55b0 100644 ---- a/.travis.dnf.conf.rawhide_latest -+++ b/.travis.dnf.conf.rawhide_latest -@@ -1,5 +1,5 @@ --[latest_$basearch] --name=Fedora - Rawhide Build - Fresh builds served by Koji - $basearch -+[latest_native] -+name=Fedora - Rawhide Build - Fresh builds served by Koji - native - failovermethod=priority - baseurl=https://kojipkgs.fedoraproject.org/repos/rawhide/latest/$basearch - enabled=1 - -From c14b7ae156e4dfb21c4c2506eb6d44e98eaa6f29 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 9 Jul 2018 11:42:05 +0200 -Subject: [PATCH 21/41] Extend badsalt tests and fix invalid pass - ---- - test-badsalt.c | 53 +++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 37 insertions(+), 16 deletions(-) - -diff --git a/test-badsalt.c b/test-badsalt.c -index 41d164a..6d57b14 100644 ---- a/test-badsalt.c -+++ b/test-badsalt.c -@@ -35,21 +35,24 @@ struct testcase - static const struct testcase testcases[] = - { - /* These strings are invalid regardless of the algorithm. */ -- { "*too short", 1, "/" }, -- { "*invalid char :", 1, ":" }, -- { "*invalid char ;", 1, ";" }, -- { "*invalid char *", 1, "*" }, -- { "*invalid char !", 1, "!" }, -- { "*invalid char \\", 1, "\\" }, -- { "*invalid white 1", 1, " " }, -- { "*invalid white 2", 1, "\t" }, -- { "*invalid white 3", 1, "\r" }, -- { "*invalid white 4", 1, "\n" }, -- { "*invalid white 5", 1, "\f" }, -- { "*invalid ctrl 1", 1, "\1" }, -- { "*invalid ctrl 2", 1, "\177" }, -- { "*failure token 1", 2, "*0" }, -- { "*failure token 2", 2, "*1" }, -+ { "*too short", 1, "/" }, -+ { "*invalid char :", 1, ":" }, -+ { "*invalid char ;", 1, ";" }, -+ { "*invalid char *", 1, "*" }, -+ { "*invalid char !", 1, "!" }, -+ { "*invalid char \\", 1, "\\" }, -+ { "*invalid white 1", 1, " " }, -+ { "*invalid white 2", 1, "\t" }, -+ { "*invalid white 3", 1, "\r" }, -+ { "*invalid white 4", 1, "\n" }, -+ { "*invalid white 5", 1, "\f" }, -+ { "*invalid ctrl 1", 1, "\1" }, -+ { "*invalid ctrl 2", 1, "\177" }, -+ { "*failure token 1", 2, "*0" }, -+ { "*failure token 2", 2, "*1" }, -+ { "*bcrypt invalid salt", 3, "$2$" }, -+ { "*unsupported algorithm", 13, "$un$upp0rt3d$" }, -+ { "*empty string", 1, "\0" }, - - /* Each of these is a valid setting string for some algorithm, - from which we will derive many invalid setting strings. -@@ -114,10 +117,14 @@ static const struct testcase testcases[] = - #endif - #if INCLUDE_md5 - { "MD5 (FreeBSD)", 12, "$1$MJHnaAke$" }, -+ { "*MD5 (FreeBSD) invalid char", 12, "$1$:JHnaAke$" }, - #endif - #if INCLUDE_sunmd5 - { "MD5 (Sun, plain)", 14, "$md5$1xMeE.at$" }, -+ { "*MD5 (Sun, plain) invalid char", 14, "$md5$:xMeE.at$" }, - { "MD5 (Sun, rounds)", 25, "$md5,rounds=123$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid char", 25, "$md5,rounds=123$:xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds", 25, "$md5,rounds=:23$1xMeE.at$" }, - #endif - #if INCLUDE_nthash - { "NTHASH (bare)", 3, "$3$" }, -@@ -125,20 +132,34 @@ static const struct testcase testcases[] = - #endif - #if INCLUDE_sha1 - { "HMAC-SHA1", 27, "$sha1$123$GGXpNqoJvglVTkGU$" }, -+ { "*HMAC-SHA1 invalid char", 27, "$sha1$123$:GXpNqoJvglVTkGU$" }, -+ { "*HMAC-SHA1 invalid rounds", 27, "$sha1$:23$GGXpNqoJvglVTkGU$" }, - #endif - #if INCLUDE_sha256 - { "SHA-256 (plain)", 20, "$5$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (plain) invalid char", 20, "$5$:JHnaAkegEVYHsFK$" }, - { "SHA-256 (rounds)", 32, "$5$rounds=1000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds", 32, "$5$rounds=:000$MJHnaAkegEVYHsFK$" }, - #endif - #if INCLUDE_sha512 - { "SHA-512 (plain)", 20, "$6$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (plain) invalid char", 20, "$6$:JHnaAkegEVYHsFK$" }, - { "SHA-512 (rounds)", 32, "$6$rounds=1000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds", 32, "$6$rounds=:000$MJHnaAkegEVYHsFK$" }, - #endif - #if INCLUDE_bcrypt - { "bcrypt (a04)", 29, "$2a$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (a04) invalid char", 29, "$2a$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (a04) invalid rounds", 29, "$2a$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "bcrypt (b04)", 29, "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (b04) invalid char", 29, "$2b$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (b04) invalid rounds", 29, "$2b$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "bcrypt (x04)", 29, "$2x$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (x04) invalid char", 29, "$2x$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (x04) invalid rounds", 29, "$2x$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "bcrypt (y04)", 29, "$2y$04$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (y04) invalid char", 29, "$2y$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (y04) invalid rounds", 29, "$2y$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, - #endif - }; - -@@ -289,7 +310,7 @@ test_one_case (const struct testcase *t, - { - printf ("FAIL: %s: initial hash returned NULL/%s (%s)\n", - t->label, cd->output, strerror (errno)); -- return 1; -+ return false; - } - - size_t l_hash = strlen (result); - -From 820e5b242e648347e9c9e4110e75842b3d6531e5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 9 Jul 2018 15:25:54 +0200 -Subject: [PATCH 22/41] Add test for short output buffers - ---- - Makefile.am | 3 ++- - test-short-outbuf.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 74 insertions(+), 1 deletion(-) - create mode 100644 test-short-outbuf.c - -diff --git a/Makefile.am b/Makefile.am -index 79d59d7..fec069e 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -126,7 +126,7 @@ check_PROGRAMS = \ - test-crypt-md5 test-crypt-nthash \ - test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \ - test-crypt-sunmd5 \ -- test-byteorder test-badsalt test-gensalt -+ test-byteorder test-badsalt test-gensalt test-short-outbuf - - if ENABLE_OBSOLETE_API - libcrypt_la_SOURCES += crypt-des-obsolete.c -@@ -169,6 +169,7 @@ test_badsalt_LDADD = libcrypt.la - test_gensalt_LDADD = libcrypt.la - test_des_obsolete_LDADD = libcrypt.la - test_des_obsolete_r_LDADD = libcrypt.la -+test_short_outbuf_LDADD = libcrypt.la - - # These tests call internal APIs that may not be accessible from the - # fully linked shared library. -diff --git a/test-short-outbuf.c b/test-short-outbuf.c -new file mode 100644 -index 0000000..7ab9d11 ---- /dev/null -+++ b/test-short-outbuf.c -@@ -0,0 +1,72 @@ -+#include "crypt-port.h" -+#include -+#include -+#include -+#include -+ -+struct testcase -+{ -+ const char *exp_rn; -+ const char *exp_ra; -+}; -+ -+static const struct testcase testcases[] = -+{ -+ { "", "*0" }, -+ { "*", "*0" }, -+ { "*0", "*0" }, -+}; -+ -+int -+main (void) -+{ -+ bool ok = true; -+ char **outbuf = malloc (sizeof (char*)); -+ char result[5]; -+ -+ for (size_t i = 0; i < ARRAY_SIZE (testcases); i++) -+ { -+ size_t *j = malloc (sizeof (size_t)); -+ -+ *j = i + 1; -+ -+ *outbuf = malloc (sizeof (char*) * *j); -+ -+ crypt_rn ("@@", "@@", *outbuf, (int) *j); -+ -+ if (!strncmp (testcases[i].exp_rn, *outbuf, *j)) -+ { -+ strcpy (result, "PASS"); -+ } -+ else -+ { -+ strcpy (result, "FAIL"); -+ ok = false; -+ } -+ -+ printf ("Test %lu.0: %s, expected: \"%-2s\", got: \"%-2s\"\n", -+ i + 1, result, testcases[i].exp_rn, *outbuf); -+ -+ crypt_ra ("@@", "@@", (void **) outbuf, (int *) j); -+ -+ if (!strncmp (testcases[i].exp_ra, *outbuf, strlen(*outbuf))) -+ { -+ strcpy (result, "PASS"); -+ } -+ else -+ { -+ strcpy (result, "FAIL"); -+ ok = false; -+ } -+ -+ printf ("Test %lu.1: %s, expected: \"%-2s\", got: \"%-2s\"\n", -+ i + 1, result, testcases[i].exp_ra, *outbuf); -+ -+ free (j); -+ free (*outbuf); -+ } -+ -+ free (outbuf); -+ -+ return ok ? 0 : 1; -+} - -From 9197a77826124683e39ef123f5e57058e358e225 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Tue, 10 Jul 2018 12:06:10 -0400 -Subject: [PATCH 23/41] Replace crypt-sunmd5.c with BSD-licensed cleanroom - reimplementation. - -This eliminates all CDDL-licensed code from the library, as requested -in issue #7 because of GPL incompatibility. - -The new implementation was based exclusively on the prose description -of the algorithm in the Passlib v1.7.1 documentation, which should be -adequately arms-length for copyright purposes. (N.B. the lengthy -quotation from _Hamlet_ is used as input to MD5, so it must remain -byte-for-byte identical to achieve interoperability with the original; -also, the play itself is in the public domain.) - -The new implementation is also fully deterministic (that is, its -gensalt procedure draws randomness only from its rbytes argument) and -does not call malloc. ---- - LICENSING | 2 +- - crypt-sunmd5.c | 543 +++++++++++++++++++++++---------------------------------- - test-gensalt.c | 8 +- - 3 files changed, 225 insertions(+), 328 deletions(-) - -diff --git a/LICENSING b/LICENSING -index b6f5168..b9df920 100644 ---- a/LICENSING -+++ b/LICENSING -@@ -28,7 +28,7 @@ source tree. For specific licensing terms consult the files themselves. - * Copyright Michael Bretterklieber, Björn Esser et al.; 2-clause BSD: - crypt-nthash.c - -- * Copyright Sun Microsystems, Inc., Björn Esser; CDDL-1.0: -+ * Copyright Zack Weinberg; 2-clause BSD: - crypt-sunmd5.c - - * Public domain, written by Steve Reid et al.: -diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c -index f3c84a8..9107052 100644 ---- a/crypt-sunmd5.c -+++ b/crypt-sunmd5.c -@@ -1,27 +1,31 @@ --/* -- * CDDL HEADER START -+/* Copyright (c) 2018 Zack Weinberg. -+ * All rights reserved. - * -- * The contents of this file are subject to the terms of the -- * Common Development and Distribution License, Version 1.0 only -- * (the "License"). You may not use this file except in compliance -- * with the License. -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. 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. - * -- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -- * or http://www.opensolaris.org/os/licensing. -- * See the License for the specific language governing permissions -- * and limitations under the License. -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * -- * When distributing Covered Code, include this CDDL HEADER in each -- * file and include the License file at usr/src/OPENSOLARIS.LICENSE. -- * If applicable, add the following below this CDDL HEADER, with the -- * fields enclosed by brackets "[]" replaced with your own identifying -- * information: Portions Copyright [yyyy] [name of copyright owner] -- * -- * CDDL HEADER END -- */ --/* -- * Copyright 2003 Sun Microsystems, Inc. All rights reserved. -- * Use is subject to license terms. -+ * This is a clean-room reimplementation of the Sun-MD5 password hash, -+ * based on the prose description of the algorithm in the Passlib v1.7.1 -+ * documentation: -+ * https://passlib.readthedocs.io/en/stable/lib/passlib.hash.sun_md5_crypt.html - */ - - #include "crypt-port.h" -@@ -34,21 +38,21 @@ - - #if INCLUDE_sunmd5 - -- --#define CRYPT_ALGNAME "md5" -- --/* minimum number of rounds we do, not including the per-user ones */ --#define BASIC_ROUND_COUNT 4096 /* enough to make things interesting */ --#define DIGEST_LEN 16 --#define ROUND_BUFFER_LEN 64 -- --/* -- * Public domain quotation courtesy of Project Gutenberg. -- * ftp://metalab.unc.edu/pub/docs/books/gutenberg/etext98/2ws2610.txt -- * Hamlet III.ii - 1517 bytes, including trailing NUL -- * ANSI-C string constant concatenation is a requirement here. -- */ --static const char constant_phrase[] = -+#define SUNMD5_PREFIX "$md5" -+#define SUNMD5_PREFIX_LEN 4 -+#define SUNMD5_SALT_LEN 8 -+#define SUNMD5_MAX_SETTING_LEN 32 /* $md5,rounds=4294963199$12345678$ */ -+#define SUNMD5_BARE_OUTPUT_LEN 22 /* not counting the setting or the NUL */ -+#define SUNMD5_MAX_ROUNDS (0xFFFFFFFF - 4096) -+ -+/* At each round of the algorithm, this string (including the trailing -+ NUL) may or may not be included in the input to MD5, depending on a -+ pseudorandom coin toss. It is Hamlet's famous soliloquy from the -+ play of the same name, which is in the public domain. Text from -+ with double -+ blank lines replaced with `\n`. Note that more recent Project -+ Gutenberg editions of _Hamlet_ are punctuated differently. */ -+static const char hamlet_quotation[] = - "To be, or not to be,--that is the question:--\n" - "Whether 'tis nobler in the mind to suffer\n" - "The slings and arrows of outrageous fortune\n" -@@ -85,346 +89,233 @@ static const char constant_phrase[] = - "The fair Ophelia!--Nymph, in thy orisons\n" - "Be all my sins remember'd.\n"; - --/* ------------------------------------------------------------------ */ -- --static int --md5bit (uint8_t *digest, int bit_num) -+/* Decide, pseudorandomly, whether or not to include the above quotation -+ in the input to MD5. */ -+static inline bool -+get_nth_bit (const uint8_t digest[16], unsigned int n) - { -- int byte_off; -- int bit_off; -- -- bit_num %= 128; /* keep this bounded for convenience */ -- byte_off = bit_num / 8; -- bit_off = bit_num % 8; -- -- /* return the value of bit N from the digest */ -- return ((digest[byte_off] & (0x01 << bit_off)) ? 1 : 0); -+ unsigned int byte = (n % 128) / 8; -+ unsigned int bit = (n % 128) % 8; -+ return !!(digest[byte] & (1 << bit)); - } - --/* 0 ... 63 => ascii - 64 */ --static unsigned char itoa64[] = -- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -- --static void --to64 (char *s, uint64_t v, int n) -+static bool -+muffet_coin_toss (const uint8_t prev_digest[16], unsigned int round_count) - { -- while (--n >= 0) -+ unsigned int x, y, a, b, r, v, i; -+ for (i = 0, x = 0, y = 0; i < 8; i++) - { -- *s++ = (char)itoa64[v&0x3f]; -- v >>= 6; -+ a = prev_digest[(i + 0) % 16]; -+ b = prev_digest[(i + 3) % 16]; -+ r = a >> (b % 5); -+ v = prev_digest[r % 16]; -+ if (b & (1u << (a % 8))) -+ v /= 2; -+ x |= ((unsigned int) +get_nth_bit (prev_digest, v)) << i; -+ -+ a = prev_digest[(i + 8) % 16]; -+ b = prev_digest[(i + 11) % 16]; -+ r = a >> (b % 5); -+ v = prev_digest[r % 16]; -+ if (b & (1u << (a % 8))) -+ v /= 2; -+ y |= ((unsigned int) +get_nth_bit (prev_digest, v)) << i; - } --} - --#define ROUNDS ",rounds=" --#define ROUNDSLEN (sizeof (ROUNDS) - 1) -+ if (get_nth_bit (prev_digest, round_count)) -+ x /= 2; -+ if (get_nth_bit (prev_digest, round_count + 64)) -+ y /= 2; - --/* -- * get the integer value after ,rounds= if present -- * s should point immediately after $md5 -- * set *puresalt one character after the dollar sign after -- * the number of rounds (if present) or to NULL if the syntax -- * is invalid -- */ --static uint32_t --getrounds (const char *s, const char **puresalt) --{ -- const char *p; -- char *e; -- long val; -- -- *puresalt = 0; -- -- if (s == NULL) -- return (0); -+ return !!(get_nth_bit (prev_digest, x) ^ get_nth_bit (prev_digest, y)); -+} - -- if (*s == '$') -- { -- *puresalt = s + 1; -- return (0); -- } -+/* itoa64 output utilities. */ -+static const unsigned char itoa64[] = -+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -- if (strncmp (s, ROUNDS, ROUNDSLEN) != 0) -- return (0); -- -- p = s + ROUNDSLEN; -- errno = 0; -- val = strtol (p, &e, 10); -- /* -- * An error occured or there is non-numeric stuff at the end -- * which isn't one of the crypt(3c) special chars ',' or '$' -- */ -- if (errno != 0 || val < 0 || p == e || (*e != '\0' && *e != '$')) -- return (0); -- -- if (*e == '$') -- *puresalt = e + 1; -- else -- *puresalt = e; -- -- return ((uint32_t)val); -+static inline void -+write_itoa64_4 (uint8_t *output, -+ unsigned int b0, unsigned int b1, unsigned int b2) -+{ -+ unsigned int value = (b0 << 0) | (b1 << 8) | (b2 << 16); -+ output[0] = itoa64[value & 0x3f]; -+ output[1] = itoa64[(value >> 6) & 0x3f]; -+ output[2] = itoa64[(value >> 12) & 0x3f]; -+ output[3] = itoa64[(value >> 18) & 0x3f]; - } - --void --gensalt_sunmd5_rn (unsigned long count, -- const uint8_t *rbytes, size_t nrbytes, -- uint8_t *output, size_t o_size) -+/* used only for the last two bytes of crypt_sunmd5_rn output */ -+static inline void -+write_itoa64_2 (uint8_t *output, -+ unsigned int b0, unsigned int b1, unsigned int b2) - { -- /* This should not happen, but. */ -- if ((nrbytes < sizeof (uint64_t)) || (o_size < 33)) -- { -- errno = ERANGE; -- return; -- } -- -- uint64_t rndval; -- char rndstr[sizeof (rndval) + 1]; /* rndval as a base64 string */ -- const uint8_t minrounds = 15; /* Min. number of rounds = 2^X */ -- -- /* Set count to a reasonable random value, -- if count was not set high enough by the -- caller. */ -- if (count < (unsigned long)(1 << minrounds)) -- { -- uint64_t rand1, rand2; -- get_random_bytes(&rand1, sizeof (uint64_t)); -- get_random_bytes(&rand2, sizeof (uint64_t)); -- count = (long unsigned int)(1 << ((rand1 % 2) + minrounds)); -- count += (long unsigned int)(rand2 % (uint64_t)((1 << (minrounds - 1)) + 1)); -- } -- -- memcpy (&rndval, rbytes, sizeof (rndval)); -- to64 ((char *)&rndstr, rndval, sizeof (rndval)); -- rndstr[sizeof (rndstr) - 1] = '\0'; -- -- /* Generated salt is at least 27 bytes -- and a maximum of 32 bytes long. */ -- snprintf ((char *)output, o_size, -- "$" CRYPT_ALGNAME ROUNDS "%u$%s$", -- (unsigned int)count, rndstr); -+ unsigned int value = (b0 << 0) | (b1 << 8) | (b2 << 16); -+ output[0] = itoa64[value & 0x3f]; -+ output[1] = itoa64[(value >> 6) & 0x3f]; - } - -+/* Module entry points. */ -+ - void --crypt_sunmd5_rn (const char *phrase, const char *setting, -- uint8_t *output, size_t o_size, -- void *scratch, size_t s_size) -+crypt_sunmd5_rn (const char *phrase, -+ const char *setting, -+ uint8_t *output, -+ size_t o_size, -+ void *scratch, -+ size_t s_size) - { -- /* put all the sensitive data in a struct */ -- struct sunmd5_ctx -+ struct crypt_sunmd5_scratch - { -- struct md5_ctx context; /* working buffer for MD5 algorithm */ -- uint8_t digest[DIGEST_LEN]; /* where the MD5 digest is stored */ -- -- int indirect_4[16]; /* extracted array of 4bit values */ -- int shift_4[16]; /* shift schedule, vals 0..4 */ -- -- int s7shift; /* shift for shift_7 creation, vals 0..7 */ -- int indirect_7[16]; /* extracted array of 7bit values */ -- int shift_7[16]; /* shift schedule, vals 0..1 */ -- -- int indirect_a; /* 7bit index into digest */ -- int shift_a; /* shift schedule, vals 0..1 */ -- -- int indirect_b; /* 7bit index into digest */ -- int shift_b; /* shift schedule, vals 0..1 */ -- -- int bit_a; /* single bit for cointoss */ -- int bit_b; /* single bit for cointoss */ -- -- char roundascii[ROUND_BUFFER_LEN]; /* ascii rep of roundcount */ -+ struct md5_ctx ctx; -+ uint8_t dg[16]; -+ char rn[16]; - }; - -- /* Scratch space needs to be large enough -- to fit struct sunmd5_ctx. Output must -- be able to fit up to 32 bytes for the -- setting + '$' + 22 bytes of hash. */ -- if (s_size < sizeof (struct sunmd5_ctx) || (o_size < 32 + 1 + 22)) -+ /* If 'setting' doesn't start with the prefix, we should not have -+ been called in the first place. */ -+ if (strncmp (setting, SUNMD5_PREFIX, SUNMD5_PREFIX_LEN) -+ || (setting[SUNMD5_PREFIX_LEN] != '$' -+ && setting[SUNMD5_PREFIX_LEN] != ',')) - { -- errno = ERANGE; -+ errno = EINVAL; - return; - } - -- /* If the magic does not match, this -- should not have been called. */ -- if (!strncmp ("$" CRYPT_ALGNAME, setting, sizeof ("$" CRYPT_ALGNAME))) -+ /* For bug-compatibility with the original implementation, we allow -+ 'rounds=' to follow either '$md5,' or '$md5$'. */ -+ const char *p = setting + SUNMD5_PREFIX_LEN + 1; -+ unsigned int nrounds = 4096; -+ if (!strncmp (p, "rounds=", sizeof "rounds=" - 1)) - { -- errno = EINVAL; -- return; -+ p += sizeof "rounds=" - 1; -+ /* Do not allow an explicit setting of zero additional rounds, -+ nor leading zeroes on the number of rounds. */ -+ if (!(*p >= '1' && *p <= '9')) -+ { -+ errno = EINVAL; -+ return; -+ } -+ -+ errno = 0; -+ char *endp; -+ unsigned long arounds = strtoul (p, &endp, 10); -+ if (endp == p || arounds > SUNMD5_MAX_ROUNDS || errno) -+ { -+ errno = EINVAL; -+ return; -+ } -+ nrounds += (unsigned int)arounds; -+ p = endp; -+ if (*p != '$') -+ { -+ errno = EINVAL; -+ return; -+ } -+ p += 1; - } - -- int i; -- int round; -- uint32_t maxrounds = BASIC_ROUND_COUNT; -- uint32_t l; -- const char *ps = 0; -- const char *saltend = 0; -- char *p, *puresalt; -- struct sunmd5_ctx *data = scratch; -- -- /* -- * Extract the rounds (if it exists) and puresalt from the salt string -- * $md5[,rounds=%d]$$ -- */ -- maxrounds += getrounds (setting + sizeof ("$" CRYPT_ALGNAME) - 1, &ps); -- if (ps) -- saltend = ps + strspn (ps, (char *)itoa64); -- if (!saltend || saltend == ps || saltend[0] != '$') -+ /* p now points to the beginning of the actual salt. */ -+ p += strspn (p, (const char *)itoa64); -+ if (*p != '\0' && *p != '$') - { - errno = EINVAL; - return; - } -- /* For bug-compatibility with the original implementation, if saltend -- points at "$$", advance it to point at the second dollar sign. */ -- if (saltend[0] == '$' && saltend[1] == '$') -- saltend += 1; -- -- if (saltend[1] != '\0') -- { -- size_t len = (size_t)(saltend - setting + 1); -- -- if ((puresalt = malloc (len)) == NULL) -- /* malloc() is supposed to set errno == ENOMEM. */ -- return; -- -- /* The original implementation used strlcpy(), -- which is not portable. Since strlcpy() -- always terminated a C string properly after -- copying len - 1 bytes of data, we need to -- do that manually. */ -- (void)strncpy (puresalt, setting, len); -- puresalt[len - 1] = '\0'; -- } -- else -+ /* For bug-compatibility with the original implementation, if p -+ points to a '$' and the following character is either another '$' -+ or NUL, the first '$' should be included in the salt. */ -+ if (p[0] == '$' && (p[1] == '$' || p[1] == '\0')) -+ p += 1; -+ -+ size_t saltlen = (size_t) (p - setting); -+ /* Do we have enough space? */ -+ if (s_size < sizeof (struct crypt_sunmd5_scratch) -+ || o_size < saltlen + SUNMD5_BARE_OUTPUT_LEN + 2) - { -- puresalt = strdup(setting); -- -- if (puresalt == NULL) -- { -- /* strdup() is supposed to set errno == ENOMEM. */ -- return; -- } -+ errno = ERANGE; -+ return; - } - -- /* initialise the context */ -- md5_init_ctx (&(data->context)); -- -- /* update with the (hopefully entropic) plaintext */ -- md5_process_bytes ((const unsigned char *)phrase, strlen (phrase), &(data->context)); -- -- /* update with the (publically known) salt */ -- md5_process_bytes ((unsigned char *)puresalt, strlen (puresalt), &(data->context)); -- -- -- /* compute the digest */ -- md5_finish_ctx (&(data->context), &(data->digest)); -+ struct crypt_sunmd5_scratch *s = scratch; - -- /* -- * now to delay high-speed md5 implementations that have stuff -- * like code inlining, loops unrolled and table lookup -- */ -+ /* Initial round. */ -+ md5_init_ctx (&s->ctx); -+ md5_process_bytes (phrase, strlen (phrase), &s->ctx); -+ md5_process_bytes (setting, saltlen, &s->ctx); -+ md5_finish_ctx (&s->ctx, s->dg); - -- for (round = 0; (uint32_t)round < maxrounds; round++) -+ /* Stretching rounds. */ -+ for (unsigned int i = 0; i < nrounds; i++) - { -- /* re-initialise the context */ -- md5_init_ctx (&(data->context)); -+ md5_init_ctx (&s->ctx); - -- /* update with the previous digest */ -- md5_process_bytes (&(data->digest), sizeof (data->digest), &(data->context)); -+ md5_process_bytes (s->dg, sizeof s->dg, &s->ctx); - -- /* populate the shift schedules for use later */ -- for (i = 0; i < 16; i++) -- { -- int j; -- -- /* offset 3 -> occasionally span more than 1 int32 fetch */ -- j = (i + 3) % 16; -- data->s7shift = data->digest[i] % 8; -- data->shift_4[i] = data->digest[j] % 5; -- data->shift_7[i] = (data->digest[j] >> data->s7shift) & 0x01; -- } -- -- data->shift_a = md5bit (data->digest, round); -- data->shift_b = md5bit (data->digest, round + 64); -- -- /* populate indirect_4 with 4bit values extracted from digest */ -- for (i = 0; i < 16; i++) -- /* shift the digest byte and extract four bits */ -- data->indirect_4[i] = (data->digest[i] >> data->shift_4[i]) & 0x0f; -- -- /* -- * populate indirect_7 with 7bit values from digest -- * indexed via indirect_4 -- */ -+ /* The trailing nul is intentionally included. */ -+ if (muffet_coin_toss (s->dg, i)) -+ md5_process_bytes (hamlet_quotation, sizeof hamlet_quotation, &s->ctx); - -- for (i = 0; i < 16; i++) -- /* shift the digest byte and extract seven bits */ -- data->indirect_7[i] = (data->digest[data->indirect_4[i]] -- >> data->shift_7[i]) & 0x7f; -+ int nwritten = snprintf (s->rn, sizeof s->rn, "%u", i); -+ assert (nwritten >= 1 && (unsigned int)nwritten + 1 <= sizeof s->rn); -+ md5_process_bytes (s->rn, (unsigned int)nwritten, &s->ctx); - -- /* -- * use the 7bit values to indirect into digest, -- * and create two 8bit values from the results. -- */ -- data->indirect_a = data->indirect_b = 0; -+ md5_finish_ctx (&s->ctx, s->dg); -+ } - -- for (i = 0; i < 8; i++) -- { -- data->indirect_a |= (md5bit (data->digest, -- data->indirect_7[i]) << i); -+ memcpy (output, setting, saltlen); -+ *(output + saltlen + 0) = '$'; -+ /* This is the same permuted order used by BSD md5-crypt ($1$). */ -+ write_itoa64_4 (output + saltlen + 1, s->dg[12], s->dg[ 6], s->dg[0]); -+ write_itoa64_4 (output + saltlen + 5, s->dg[13], s->dg[ 7], s->dg[1]); -+ write_itoa64_4 (output + saltlen + 9, s->dg[14], s->dg[ 8], s->dg[2]); -+ write_itoa64_4 (output + saltlen + 13, s->dg[15], s->dg[ 9], s->dg[3]); -+ write_itoa64_4 (output + saltlen + 17, s->dg[ 5], s->dg[10], s->dg[4]); -+ write_itoa64_2 (output + saltlen + 21, s->dg[11], 0, 0); -+ *(output + saltlen + 23) = '\0'; -+} - -- data->indirect_b |= (md5bit (data->digest, -- data->indirect_7[i + 8]) << i); -- } -+void -+gensalt_sunmd5_rn (unsigned long count, -+ const uint8_t *rbytes, -+ size_t nrbytes, -+ uint8_t *output, -+ size_t o_size) -+{ -+ if (o_size < SUNMD5_MAX_SETTING_LEN + 1 || nrbytes < 6 + 2) -+ { -+ errno = ERANGE; -+ return; -+ } -+ if (count > SUNMD5_MAX_ROUNDS) -+ { -+ errno = EINVAL; -+ return; -+ } - -- /* shall we utilise the top or bottom 7 bits? */ -- data->indirect_a = (data->indirect_a >> data->shift_a) & 0x7f; -- data->indirect_b = (data->indirect_b >> data->shift_b) & 0x7f; -+ /* The default number of rounds, 4096, is much too low. The actual -+ number of rounds is somewhat randomized to make construction of -+ rainbow tables more difficult (effectively this means an extra 16 -+ bits of entropy are smuggled into the salt via the round number). */ -+ if (count < 32768) -+ count = 32768; -+ else if (count + 65536 > SUNMD5_MAX_ROUNDS) -+ count = SUNMD5_MAX_ROUNDS - 65536; - -- /* extract two data->digest bits */ -- data->bit_a = md5bit (data->digest, data->indirect_a); -- data->bit_b = md5bit (data->digest, data->indirect_b); -+ count += ((unsigned int)rbytes[0]) << 8; -+ count += ((unsigned int)rbytes[1]) << 0; - -- /* xor a coin-toss; if true, mix-in the constant phrase */ -+ assert (count != 0); - -- if (data->bit_a ^ data->bit_b) -- md5_process_bytes ((const unsigned char *) constant_phrase, -- sizeof (constant_phrase), -- &(data->context)); -+ size_t written = (size_t) snprintf ((char *)output, o_size, -+ "%s,rounds=%lu$", SUNMD5_PREFIX, count); - -- /* digest a decimal sprintf of the current roundcount */ -- snprintf (data->roundascii, ROUND_BUFFER_LEN, "%d", round); -- md5_process_bytes ((unsigned char *) data->roundascii, -- strlen (data->roundascii), -- &(data->context)); - -- /* compute/flush the digest, and loop */ -- md5_finish_ctx (&(data->context), &(data->digest)); -- } -+ write_itoa64_4(output + written + 0, rbytes[2], rbytes[3], rbytes[4]); -+ write_itoa64_4(output + written + 4, rbytes[5], rbytes[6], rbytes[7]); - -- (void)snprintf ((char *)output, o_size, "%s$", puresalt); -- -- free (puresalt); -- -- p = (char *)output + strlen ((const char *)output); -- -- l = (uint32_t)((data->digest[ 0]<<16) | (data->digest[ 6]<<8) | data->digest[12]); -- to64 (p, l, 4); -- p += 4; -- l = (uint32_t)((data->digest[ 1]<<16) | (data->digest[ 7]<<8) | data->digest[13]); -- to64 (p, l, 4); -- p += 4; -- l = (uint32_t)((data->digest[ 2]<<16) | (data->digest[ 8]<<8) | data->digest[14]); -- to64 (p, l, 4); -- p += 4; -- l = (uint32_t)((data->digest[ 3]<<16) | (data->digest[ 9]<<8) | data->digest[15]); -- to64 (p, l, 4); -- p += 4; -- l = (uint32_t)((data->digest[ 4]<<16) | (data->digest[10]<<8) | data->digest[ 5]); -- to64 (p, l, 4); -- p += 4; -- l = (uint32_t)data->digest[11]; -- to64 (p, l, 2); -- p += 2; -- *p = '\0'; -+ output[written + 8] = '$'; -+ output[written + 9] = '\0'; - } - - #endif -diff --git a/test-gensalt.c b/test-gensalt.c -index c08627e..f8d95c3 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -45,7 +45,13 @@ static const char *const nthash_expected_output[] = - }; - #endif - #if INCLUDE_sunmd5 --#define sunmd5_expected_output 0 /* output is not deterministic */ -+static const char *const sunmd5_expected_output[] = -+{ -+ "$md5,rounds=55349$BPm.fm03$", -+ "$md5,rounds=72501$WKoucttX$", -+ "$md5,rounds=42259$3HtkHq/x$", -+ "$md5,rounds=73773$p.5e9AQf$", -+}; - #endif - #if INCLUDE_sha1 - #define pbkdf_expected_output 0 /* output is not deterministic */ - -From 4067bee9f5b24d5323af232ef25f3b6dc4950f5a Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Tue, 10 Jul 2018 20:32:11 -0400 -Subject: [PATCH 24/41] Make crypt_gensalt for $sha1 deterministic. - -All of the randomness is now drawn from the 'rbytes' argument, rather -than taking some of it from direct calls to get_random_bytes. This -simplifies the logic and enables us to test the output more -thoroughly. - -Relatedly, the amount of randomness crypt_gensalt will supply to $sha1 -and $3 when it calls get_random_bytes itself is no longer oversized. ---- - crypt-pbkdf1-sha1.c | 90 ++++++++++++++++++++++++++--------------------------- - hashes.lst | 9 +++--- - test-gensalt.c | 13 +++++--- - 3 files changed, 59 insertions(+), 53 deletions(-) - -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index 6bacc21..ac201f0 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -66,34 +66,6 @@ to64 (uint8_t *s, unsigned long v, int n) - } - } - --/* -- * This may be called from crypt_sha1 or gensalt. -- * -- * The value returned will be slightly less than which defaults -- * to 24680. The goals are that the number of iterations should take -- * non-zero amount of time on a fast cpu while not taking insanely -- * long on a slow cpu. The current default will take about 5 seconds -- * on a 100MHz sparc, and about 0.04 seconds on a 3GHz i386. -- * The number is varied to frustrate those attempting to generate a -- * dictionary of pre-computed hashes. -- */ --static unsigned long --crypt_sha1_iterations (unsigned long hint) --{ -- unsigned long random; -- -- /* -- * We treat CRYPT_SHA1_ITERATIONS as a hint. -- * Make it harder for someone to pre-compute hashes for a -- * dictionary attack by not using the same iteration count for -- * every entry. -- */ -- get_random_bytes (&random, sizeof (unsigned long)); -- if (hint == 0) -- hint = CRYPT_SHA1_ITERATIONS; -- return hint - (random % (hint / 4)); --} -- - /* - * UNIX password using hmac_sha1 - * This is PBKDF1 from RFC 2898, but using hmac_sha1. -@@ -107,7 +79,7 @@ crypt_sha1_iterations (unsigned long hint) - * have been applied to . The number - * should vary slightly for each password to make - * it harder to generate a dictionary of -- * pre-computed hashes. See crypt_sha1_iterations. -+ * pre-computed hashes. See gensalt_sha1_rn. - * up to 64 bytes of random data, 8 bytes is - * currently considered more than enough. - * the hashed password. -@@ -234,34 +206,62 @@ gensalt_sha1_rn (unsigned long count, - const uint8_t *rbytes, size_t nrbytes, - uint8_t *output, size_t o_size) - { -- /* The salt can be up to 64 bytes, but 32 -- is considered enough for now. */ -- const uint8_t saltlen = 16; -+ static_assert (sizeof (uint32_t) == 4, -+ "space calculations below assume 8-bit bytes"); - -- const size_t enclen = sizeof (unsigned long)*4/3; -+ /* Make sure we have enough random bytes to use for the salt. -+ The format supports using up to 48 random bytes, but 12 is -+ enough. We require another 4 bytes of randomness to perturb -+ 'count' with. */ -+ if (nrbytes < 12 + 4) -+ { -+ errno = ERANGE; -+ return; -+ } - -- if ((o_size < (size_t)(6 + CRYPT_SHA1_SALT_LENGTH + 2)) || -- ((nrbytes*4/3) < saltlen)) -+ /* Make sure we have enough output space, given the amount of -+ randomness available. $sha1$<10digits>$<(nrbytes-4)*4/3>$ */ -+ if (o_size < (nrbytes - 4) * 4 / 3 + sizeof "$sha1$$$" + 10) - { - errno = ERANGE; - return; - } - -- unsigned long c, encbuf; -+ /* -+ * We treat 'count' as a hint. -+ * Make it harder for someone to pre-compute hashes for a -+ * dictionary attack by not using the same iteration count for -+ * every entry. -+ */ -+ uint32_t rounds, random; -+ memcpy (&random, rbytes, 4); -+ if (count == 0) -+ count = CRYPT_SHA1_ITERATIONS; -+ if (count > UINT32_MAX) -+ count = UINT32_MAX; -+ rounds = (uint32_t) (count - (random % (count / 4))); -+ -+ uint32_t encbuf; -+ int n = snprintf((char *)output, o_size, "$sha1$%u$", (unsigned int)rounds); -+ assert (n >= 1 && (size_t)n + 2 < o_size); - -- unsigned int n = (unsigned int) snprintf((char *)output, o_size, "$sha1$%u$", -- (unsigned int)crypt_sha1_iterations(count)); -+ const uint8_t *r = rbytes + 4; -+ const uint8_t *rlim = rbytes + nrbytes; -+ uint8_t *o = output + n; -+ uint8_t *olim = output + n + CRYPT_SHA1_SALT_LENGTH; -+ if (olim + 2 > output + o_size) -+ olim = output + o_size - 2; - -- for (c = 0; (c * sizeof (unsigned long)) + sizeof (unsigned long) <= nrbytes && -- (c * enclen) + enclen <= CRYPT_SHA1_SALT_LENGTH; ++c) -+ for (; r + 3 < rlim && o + 4 < olim; r += 3, o += 4) - { -- memcpy (&encbuf, rbytes + (c * sizeof (unsigned long)), -- sizeof (unsigned long)); -- to64 (output + n + (c * enclen), encbuf, (int)enclen); -+ encbuf = ((((uint32_t)r[0]) << 16) | -+ (((uint32_t)r[1]) << 8) | -+ (((uint32_t)r[2]) << 0)); -+ to64 (o, encbuf, 4); - } - -- output[n + (c * enclen)] = '$'; -- output[n + (c * enclen) + 1] = '\0'; -+ o[0] = '$'; -+ o[1] = '\0'; - } - - #endif -diff --git a/hashes.lst b/hashes.lst -index 488768f..4ec79cc 100644 ---- a/hashes.lst -+++ b/hashes.lst -@@ -5,8 +5,9 @@ - # name used for the 'crypt_fn' and 'gensalt_fn' entry points to the - # relevant algorithm module; an optional suffix on the name of the - # 'gensalt_fn'; the prefix used to identify the algorithm in hash --# strings; the number of bytes of random data required to generate a --# salt; and a set of flags. Currently there are three flags: DEFAULT -+# strings; the number of bytes of random data that crypt_gensalt -+# should draw from the OS when its caller doesn't supply any; -+# and a set of flags. Currently there are three flags: DEFAULT - # means this is the hash to use when no prefix was supplied to - # crypt_gensalt, STRONG means the hash is still considered strong - # enough to use for newly hashed passwords, and GLIBC means the hash -@@ -33,8 +34,8 @@ sha512 : $6$ 15 STRONG,GLIBC - sha256 : $5$ 15 STRONG,GLIBC - md5 : $1$ 9 GLIBC - sunmd5 : $md5 8 : --sha1 : $sha1 48 : --nthash : $3$ 16 : -+sha1 : $sha1 20 : -+nthash : $3$ 7 : - des_xbsd : _ 3 : - des_big : : 2 : - des : : 2 GLIBC -diff --git a/test-gensalt.c b/test-gensalt.c -index f8d95c3..98923e5 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -54,7 +54,13 @@ static const char *const sunmd5_expected_output[] = - }; - #endif - #if INCLUDE_sha1 --#define pbkdf_expected_output 0 /* output is not deterministic */ -+static const char *const pbkdf_expected_output[] = -+{ -+ "$sha1$248488$ggu.H673kaZ5$", -+ "$sha1$248421$SWqudaxXA5L0$", -+ "$sha1$257243$RAtkIrDxEovH$", -+ "$sha1$250464$1j.eVxRfNAPO$", -+}; - #endif - #if INCLUDE_sha256 - static const char *const sha256_expected_output[] = -@@ -131,7 +137,7 @@ static const struct testcase testcases[] = - { "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5 - #endif - #if INCLUDE_sha1 -- { "$sha1", pbkdf_expected_output, 34, 74 }, // PBKDF with SHA1 -+ { "$sha1", pbkdf_expected_output, 26, 34 }, // PBKDF with SHA1 - #endif - #if INCLUDE_sha256 - { "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256 -@@ -203,8 +209,7 @@ main (void) - tcase->prefix, ent, salt); - status = 1; - } -- else if (entropy[ent] && tcase->expected_output && -- strcmp (salt, tcase->expected_output[ent])) -+ else if (entropy[ent] && strcmp (salt, tcase->expected_output[ent])) - { - fprintf (stderr, "ERROR: %s/%u -> %s (expected %s)\n", - tcase->prefix, ent, salt, tcase->expected_output[ent]); - -From 9bed27f2bd0495361e892a0740bcdf237f560b98 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Tue, 10 Jul 2018 21:36:11 -0400 -Subject: [PATCH 25/41] Don't use malloc in crypt-pbkdf1-sha1.c. - -There's no need to copy the salt when we can just use %.*s in two -places. - -Making this change revealed that -Wformat-truncation=2 is too -aggressive; we are actually taking appropriate precautions against -truncated strings in this case, but it warns anyway. Back down to --Wformat-truncation=1, which warns only when the return value of -snprintf is ignored. ---- - crypt-pbkdf1-sha1.c | 20 ++++++-------------- - m4/zw_simple_warnings.m4 | 2 +- - 2 files changed, 7 insertions(+), 15 deletions(-) - -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index ac201f0..cbf390e 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -109,7 +109,6 @@ crypt_sha1_rn (const char *phrase, const char *setting, - unsigned long ul; - size_t sl; - size_t pl; -- char *salt; - int dl; - unsigned long iterations; - unsigned long i; -@@ -148,32 +147,27 @@ crypt_sha1_rn (const char *phrase, const char *setting, - return; - } - -- /* Get the length of the actual salt */ - sl = (size_t)(sp - setting); -- -- salt = malloc (sl + 1); -- strncpy (salt, setting, sl); -- salt[sl] = '\0'; -- - pl = strlen (phrase); - - /* - * Now get to work... - * Prime the pump with - */ -- dl = snprintf ((char *)output, o_size, "%s%s%lu", -- salt, magic, iterations); -+ dl = snprintf ((char *)output, o_size, "%.*s%s%lu", -+ (int)sl, setting, magic, iterations); - /* - * Then hmac using as key, and repeat... - */ -- hmac_sha1_process_data ((const unsigned char *)output, (size_t)dl, pwu, pl, hmac_buf); -+ hmac_sha1_process_data ((const unsigned char *)output, (size_t)dl, -+ pwu, pl, hmac_buf); - for (i = 1; i < iterations; ++i) - { - hmac_sha1_process_data (hmac_buf, SHA1_SIZE, pwu, pl, hmac_buf); - } - /* Now output... */ -- pl = (size_t)snprintf ((char *)output, o_size, "%s%lu$%s$", -- magic, iterations, salt); -+ pl = (size_t)snprintf ((char *)output, o_size, "%s%lu$%.*s$", -+ magic, iterations, (int)sl, setting); - ep = output + pl; - - /* Every 3 bytes of hash gives 24 bits which is 4 base64 chars */ -@@ -195,8 +189,6 @@ crypt_sha1_rn (const char *phrase, const char *setting, - - /* Don't leave anything around in vm they could use. */ - XCRYPT_SECURE_MEMSET (scratch, s_size) -- XCRYPT_SECURE_MEMSET (salt, sl) -- free (salt); - } - - /* Modified excerpt from: -diff --git a/m4/zw_simple_warnings.m4 b/m4/zw_simple_warnings.m4 -index eeb57d5..75ca300 100644 ---- a/m4/zw_simple_warnings.m4 -+++ b/m4/zw_simple_warnings.m4 -@@ -112,7 +112,7 @@ AC_ARG_ENABLE( - -Wformat=2 dnl - -Wformat-overflow=2 dnl - -Wformat-signedness dnl -- -Wformat-truncation=2 dnl -+ -Wformat-truncation=1 dnl - -Winline dnl - -Wlogical-op dnl - -Wmissing-declarations dnl - -From c20f9f161c0aa362e0ed8bc8ee387badd8acbc38 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Tue, 10 Jul 2018 21:44:02 -0400 -Subject: [PATCH 26/41] Fix incorrect output-size computation in crypt_sha1_rn. - -It was testing for enough space for the raw SHA1 digest, not the -digest after base64 expansion. - -(This is not presently detectable by the test suite because the higher -layers always supply crypt__rn functions with CRYPT_OUTPUT_SIZE -bytes of space, which is far more than any of them need.) ---- - crypt-pbkdf1-sha1.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index cbf390e..c96b72d 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -51,7 +51,8 @@ - # define CRYPT_SHA1_SALT_LENGTH 64 - #endif - --#define SHA1_SIZE 20 -+#define SHA1_SIZE 20 /* size of raw SHA1 digest, 160 bits */ -+#define SHA1_OUTPUT_SIZE 28 /* size of base64-ed output string */ - - static const uint8_t itoa64[] = - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -@@ -97,7 +98,8 @@ crypt_sha1_rn (const char *phrase, const char *setting, - { - static const char *magic = "$sha1$"; - -- if ((o_size < (strlen (magic) + 2 + 10 + CRYPT_SHA1_SALT_LENGTH + SHA1_SIZE)) || -+ if ((o_size < (strlen (magic) + 2 + 10 + CRYPT_SHA1_SALT_LENGTH + -+ SHA1_OUTPUT_SIZE)) || - s_size < SHA1_SIZE) - { - errno = ERANGE; - -From 8639108dea0b847282e1de2bae6c7aef8f778b99 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Tue, 10 Jul 2018 21:49:14 -0400 -Subject: [PATCH 27/41] Make XCRYPT_SECURE_MEMSET() syntactically a normal - expression. - -All of the alternative definitions of XCRYPT_SECURE_MEMSET expanded to -a full statement including the terminating semicolon, and none of its -uses had a terminating semicolon, which looked like a typo. Correct -this: put semicolons on each use, and remove them from the -definitions. This is entirely cosmetic, but it's been bugging me. - -(There is no risk of unexpected parser behavior after macro expansion: -after this change, XCRYPT_SECURE_MEMSET(...) looks like a function -call expression, and all of its possible expansions are, in fact, -function call expressions.) ---- - alg-md4.c | 6 +++--- - alg-md5.c | 4 ++-- - alg-sha1.c | 4 ++-- - alg-sha256.c | 4 ++-- - alg-sha512.c | 4 ++-- - crypt-des-obsolete.c | 2 +- - crypt-des.c | 4 ++-- - crypt-nthash.c | 2 +- - crypt-pbkdf1-sha1.c | 2 +- - crypt-port.h | 8 ++++---- - crypt.c | 2 +- - randombytes.c | 2 +- - 12 files changed, 22 insertions(+), 22 deletions(-) - -diff --git a/alg-md4.c b/alg-md4.c -index ce62490..c1c4075 100644 ---- a/alg-md4.c -+++ b/alg-md4.c -@@ -163,7 +163,7 @@ md4_read_ctx (struct md4_ctx *ctx, void *resbuf) - cpu_to_le32 (buf + 4, ctx->b); - cpu_to_le32 (buf + 8, ctx->c); - cpu_to_le32 (buf + 12, ctx->d); -- XCRYPT_SECURE_MEMSET (ctx, sizeof(struct md4_ctx)) -+ XCRYPT_SECURE_MEMSET (ctx, sizeof(struct md4_ctx)); - return resbuf; - } - -@@ -230,13 +230,13 @@ md4_finish_ctx (struct md4_ctx *ctx, void *resbuf) - - if (free < 8) - { -- XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free) -+ XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free); - body(ctx, ctx->buffer, 64); - used = 0; - free = 64; - } - -- XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free - 8) -+ XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free - 8); - - ctx->lo <<= 3; - ctx->buffer[56] = (unsigned char)((ctx->lo) & 0xff); -diff --git a/alg-md5.c b/alg-md5.c -index df49fc6..9d9e4e3 100644 ---- a/alg-md5.c -+++ b/alg-md5.c -@@ -52,7 +52,7 @@ md5_read_ctx (struct md5_ctx *ctx, void *resbuf) - cpu_to_le32 (buf + 4, ctx->B); - cpu_to_le32 (buf + 8, ctx->C); - cpu_to_le32 (buf + 12, ctx->D); -- XCRYPT_SECURE_MEMSET (ctx, sizeof(*ctx)) -+ XCRYPT_SECURE_MEMSET (ctx, sizeof(*ctx)); - return resbuf; - } - -@@ -74,7 +74,7 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) - /* The first byte of padding should be 0x80 and the rest should be - zero. (RFC 1321, 3.1: Step 1) */ - ctx->buffer[bytes] = 0x80u; -- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1) -+ XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1); - - /* Put the 64-bit file length in little-endian *bits* at the end of - the buffer. */ -diff --git a/alg-sha1.c b/alg-sha1.c -index 421ffbd..a00b06b 100644 ---- a/alg-sha1.c -+++ b/alg-sha1.c -@@ -274,8 +274,8 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) - - /* Wipe variables */ - i = 0; -- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha1_ctx)) -- XCRYPT_SECURE_MEMSET (finalcount, 8) /* SWR */ -+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha1_ctx)); -+ XCRYPT_SECURE_MEMSET (finalcount, 8); /* SWR */ - - return resbuf; - } -diff --git a/alg-sha256.c b/alg-sha256.c -index 713385d..db4a2fd 100644 ---- a/alg-sha256.c -+++ b/alg-sha256.c -@@ -183,7 +183,7 @@ sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) - /* The first byte of padding should be 0x80 and the rest should be - zero. (FIPS 180-2:5.1.1) */ - ctx->buffer[bytes] = 0x80u; -- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1) -+ XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1); - - /* Put the 64-bit file length in big-endian *bits* at the end of the - buffer. */ -@@ -196,7 +196,7 @@ sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) - for (i = 0; i < 8; i++) - cpu_to_be32 (rp + i*4, ctx->H[i]); - -- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha256_ctx)) -+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha256_ctx)); - return resbuf; - } - -diff --git a/alg-sha512.c b/alg-sha512.c -index 6a6aab2..60c1877 100644 ---- a/alg-sha512.c -+++ b/alg-sha512.c -@@ -213,7 +213,7 @@ sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) - /* The first byte of padding should be 0x80 and the rest should be - zero. (FIPS 180-2:5.1.2) */ - ctx->buffer[bytes] = 0x80u; -- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1) -+ XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1); - - /* Put the 128-bit file length in big-endian *bits* at the end of - the buffer. */ -@@ -229,7 +229,7 @@ sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) - for (i = 0; i < 8; ++i) - cpu_to_be64 (rp + i*8, ctx->H[i]); - -- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha512_ctx)) -+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha512_ctx)); - return resbuf; - } - -diff --git a/crypt-des-obsolete.c b/crypt-des-obsolete.c -index afe279b..52853e3 100644 ---- a/crypt-des-obsolete.c -+++ b/crypt-des-obsolete.c -@@ -106,7 +106,7 @@ pack_bits (unsigned char bitv[8], const char bytev[64]) - static void - do_setkey_r (const char *key, struct des_ctx *ctx) - { -- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct des_ctx)) -+ XCRYPT_SECURE_MEMSET (ctx, sizeof (struct des_ctx)); - des_set_salt (ctx, 0); - - unsigned char bkey[8]; -diff --git a/crypt-des.c b/crypt-des.c -index b197dcd..733c4d3 100644 ---- a/crypt-des.c -+++ b/crypt-des.c -@@ -107,7 +107,7 @@ des_gen_hash (struct des_ctx *ctx, uint32_t count, uint8_t *output, - uint8_t cbuf[8]) - { - uint8_t plaintext[8]; -- XCRYPT_SECURE_MEMSET (plaintext, 8) -+ XCRYPT_SECURE_MEMSET (plaintext, 8); - des_crypt_block (ctx, cbuf, plaintext, count, false); - - /* Now encode the result. */ -@@ -369,7 +369,7 @@ crypt_des_xbsd_rn (const char *phrase, const char *setting, - set as the DES key, and encrypted to produce the round output. - The salt is zero throughout this procedure. */ - des_set_salt (ctx, 0); -- XCRYPT_SECURE_MEMSET (pkbuf, 8) -+ XCRYPT_SECURE_MEMSET (pkbuf, 8); - for (;;) - { - for (i = 0; i < 8; i++) -diff --git a/crypt-nthash.c b/crypt-nthash.c -index f9fee7b..890f57f 100644 ---- a/crypt-nthash.c -+++ b/crypt-nthash.c -@@ -78,7 +78,7 @@ crypt_nthash_rn (const char *phrase, - return; - } - -- XCRYPT_SECURE_MEMSET (unipw, sizeof unipw) -+ XCRYPT_SECURE_MEMSET (unipw, sizeof unipw); - /* convert to unicode (thanx Archie) */ - unipwLen = 0; - for (s = phrase; unipwLen < sizeof(unipw) / 2 && *s; s++) -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index c96b72d..f15b55d 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -190,7 +190,7 @@ crypt_sha1_rn (const char *phrase, const char *setting, - *ep = '\0'; - - /* Don't leave anything around in vm they could use. */ -- XCRYPT_SECURE_MEMSET (scratch, s_size) -+ XCRYPT_SECURE_MEMSET (scratch, s_size); - } - - /* Modified excerpt from: -diff --git a/crypt-port.h b/crypt-port.h -index 6d94b09..80fa489 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -95,15 +95,15 @@ typedef union - #if defined HAVE_MEMSET_S - /* Will never be optimized out. */ - #define XCRYPT_SECURE_MEMSET(s, len) \ -- memset_s (s, len, 0x00, len); -+ memset_s (s, len, 0x00, len) - #elif defined HAVE_EXPLICIT_BZERO - /* explicit_bzero() should give us enough guarantees. */ - #define XCRYPT_SECURE_MEMSET(s, len) \ -- explicit_bzero(s, len); -+ explicit_bzero(s, len) - #elif defined HAVE_EXPLICIT_MEMSET - /* Same guarantee goes for explicit_memset(). */ - #define XCRYPT_SECURE_MEMSET(s, len) \ -- explicit_memset (s, 0x00, len); -+ explicit_memset (s, 0x00, len) - #else - /* The best hope we have in this case. */ - static inline -@@ -114,7 +114,7 @@ void _xcrypt_secure_memset (void *s, size_t len) - *c++ = 0x00; - } - #define XCRYPT_SECURE_MEMSET(s, len) \ -- _xcrypt_secure_memset (s, len); -+ _xcrypt_secure_memset (s, len) - #endif - - /* Per-symbol version tagging. Currently we only know how to do this -diff --git a/crypt.c b/crypt.c -index 387b69a..405d9a3 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -259,7 +259,7 @@ do_crypt (const char *phrase, const char *setting, struct crypt_data *data) - #endif - } - -- XCRYPT_SECURE_MEMSET (data->internal, sizeof data->internal) -+ XCRYPT_SECURE_MEMSET (data->internal, sizeof data->internal); - } - - #if INCLUDE_crypt_rn -diff --git a/randombytes.c b/randombytes.c -index 5647250..5053525 100644 ---- a/randombytes.c -+++ b/randombytes.c -@@ -68,7 +68,7 @@ get_random_bytes(void *buf, size_t buflen) - } - /* To eliminate the possibility of one of the primitives below failing - with EFAULT, force a crash now if the buffer is unwritable. */ -- XCRYPT_SECURE_MEMSET (buf, buflen) -+ XCRYPT_SECURE_MEMSET (buf, buflen); - - #ifdef HAVE_ARC4RANDOM_BUF - /* arc4random_buf, if it exists, can never fail. */ - -From 15d1e3bf3d259ea262f3d34e8c225a3abfabaa09 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Wed, 11 Jul 2018 17:15:46 -0400 -Subject: [PATCH 28/41] Add more tests based on gaps in line coverage. - -We were not adequately testing invalid-argument error paths within -crypt_gensalt, and we were also not adequately testing a variety of -corner cases related to non-default round parameters - -After this change, I believe that all of the non-covered lines fall -into three categories: genuinely impossible to hit from the public -API (usually these are double-checks for preconditions already -verified at a higher level); checks for memory allocation failure; and -fallback paths within get_random_bytes. The first two of these, IMHO, -are fine to leave as is. It would probably be worth writing a test -that exercises the get_random_bytes fallbacks but it'd involve getting -one's hands dirty with ELF. I may do it eventually if no one else does. - -This change makes us pickier about non-default round parameters to $5$ -and $6$ hashes; numbers outside the valid range are now rejected, as -are numbers with leading zeroes and an explicit request for the -default number of rounds. This is in keeping with the observation, in -the Passlib documentation, that allowing more than one valid crypt -output string for any given (rounds, salt, phrase) triple is asking -for trouble. - -This partially reverts commit -a7f9df50cecec46bb8176382faa685ce35ca72be, which accidentally caused us -to fail to reject invalid DES setting strings. Because of this, a few -lines in crypt-des.c cease to be covered; they are in category -1 (double-checks of preconditions). ---- - Makefile.am | 4 +- - crypt-pbkdf1-sha1.c | 2 +- - crypt-sha256.c | 26 ++++-- - crypt-sha512.c | 26 ++++-- - crypt-sunmd5.c | 4 +- - crypt.c | 13 ++- - test-badsalt.c | 40 +++++++-- - test-badsetting.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - test-crypt-sha256.c | 10 --- - test-crypt-sha512.c | 10 --- - test-gensalt.c | 82 ++++++++++++++---- - 11 files changed, 391 insertions(+), 62 deletions(-) - create mode 100644 test-badsetting.c - -diff --git a/Makefile.am b/Makefile.am -index fec069e..51cba76 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -126,7 +126,8 @@ check_PROGRAMS = \ - test-crypt-md5 test-crypt-nthash \ - test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \ - test-crypt-sunmd5 \ -- test-byteorder test-badsalt test-gensalt test-short-outbuf -+ test-byteorder test-badsalt test-badsetting test-gensalt \ -+ test-short-outbuf - - if ENABLE_OBSOLETE_API - libcrypt_la_SOURCES += crypt-des-obsolete.c -@@ -166,6 +167,7 @@ test_crypt_sha256_LDADD = libcrypt.la - test_crypt_sha512_LDADD = libcrypt.la - test_crypt_sunmd5_LDADD = libcrypt.la - test_badsalt_LDADD = libcrypt.la -+test_badsetting_LDADD = libcrypt.la - test_gensalt_LDADD = libcrypt.la - test_des_obsolete_LDADD = libcrypt.la - test_des_obsolete_r_LDADD = libcrypt.la -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index f15b55d..cf22f67 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -209,7 +209,7 @@ gensalt_sha1_rn (unsigned long count, - 'count' with. */ - if (nrbytes < 12 + 4) - { -- errno = ERANGE; -+ errno = EINVAL; - return; - } - -diff --git a/crypt-sha256.c b/crypt-sha256.c -index b8640b8..22c6423 100644 ---- a/crypt-sha256.c -+++ b/crypt-sha256.c -@@ -111,7 +111,6 @@ crypt_sha256_rn (const char *phrase, const char *setting, - size_t cnt; - /* Default number of rounds. */ - size_t rounds = ROUNDS_DEFAULT; -- bool rounds_custom = false; - - /* Find beginning of salt string. The prefix should normally always - be present. Just in case it is not. */ -@@ -123,14 +122,27 @@ crypt_sha256_rn (const char *phrase, const char *setting, - == 0) - { - const char *num = salt + sizeof (sha256_rounds_prefix) - 1; -+ /* Do not allow an explicit setting of zero rounds, nor of the -+ default number of rounds, nor leading zeroes on the rounds. */ -+ if (!(*num >= '1' && *num <= '9')) -+ { -+ errno = EINVAL; -+ return; -+ } -+ -+ errno = 0; - char *endp; -- unsigned long int srounds = strtoul (num, &endp, 10); -- if (*endp == '$') -+ rounds = strtoul (num, &endp, 10); -+ if (endp == num || *endp != '$' -+ || rounds < ROUNDS_MIN -+ || rounds > ROUNDS_MAX -+ || rounds == ROUNDS_DEFAULT -+ || errno) - { -- salt = endp + 1; -- rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX)); -- rounds_custom = true; -+ errno = EINVAL; -+ return; - } -+ salt = endp + 1; - } - - salt_len = strspn (salt, b64t); -@@ -243,7 +255,7 @@ crypt_sha256_rn (const char *phrase, const char *setting, - memcpy (cp, sha256_salt_prefix, sizeof (sha256_salt_prefix) - 1); - cp += sizeof (sha256_salt_prefix) - 1; - -- if (rounds_custom) -+ if (rounds != ROUNDS_DEFAULT) - { - int n = snprintf (cp, - SHA256_HASH_LENGTH - (sizeof (sha256_salt_prefix) - 1), -diff --git a/crypt-sha512.c b/crypt-sha512.c -index 1a651e0..7df4805 100644 ---- a/crypt-sha512.c -+++ b/crypt-sha512.c -@@ -111,7 +111,6 @@ crypt_sha512_rn (const char *phrase, const char *setting, - size_t cnt; - /* Default number of rounds. */ - size_t rounds = ROUNDS_DEFAULT; -- bool rounds_custom = false; - - /* Find beginning of salt string. The prefix should normally always - be present. Just in case it is not. */ -@@ -123,14 +122,27 @@ crypt_sha512_rn (const char *phrase, const char *setting, - == 0) - { - const char *num = salt + sizeof (sha512_rounds_prefix) - 1; -+ /* Do not allow an explicit setting of zero rounds, nor of the -+ default number of rounds, nor leading zeroes on the rounds. */ -+ if (!(*num >= '1' && *num <= '9')) -+ { -+ errno = EINVAL; -+ return; -+ } -+ -+ errno = 0; - char *endp; -- unsigned long int srounds = strtoul (num, &endp, 10); -- if (*endp == '$') -+ rounds = strtoul (num, &endp, 10); -+ if (endp == num || *endp != '$' -+ || rounds < ROUNDS_MIN -+ || rounds > ROUNDS_MAX -+ || rounds == ROUNDS_DEFAULT -+ || errno) - { -- salt = endp + 1; -- rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX)); -- rounds_custom = true; -+ errno = EINVAL; -+ return; - } -+ salt = endp + 1; - } - - salt_len = strspn (salt, b64t); -@@ -246,7 +258,7 @@ crypt_sha512_rn (const char *phrase, const char *setting, - memcpy (cp, sha512_salt_prefix, sizeof (sha512_salt_prefix) - 1); - cp += sizeof (sha512_salt_prefix) - 1; - -- if (rounds_custom) -+ if (rounds != ROUNDS_DEFAULT) - { - int n = snprintf (cp, - SHA512_HASH_LENGTH - (sizeof (sha512_salt_prefix) - 1), -diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c -index 9107052..c294797 100644 ---- a/crypt-sunmd5.c -+++ b/crypt-sunmd5.c -@@ -282,12 +282,12 @@ gensalt_sunmd5_rn (unsigned long count, - uint8_t *output, - size_t o_size) - { -- if (o_size < SUNMD5_MAX_SETTING_LEN + 1 || nrbytes < 6 + 2) -+ if (o_size < SUNMD5_MAX_SETTING_LEN + 1) - { - errno = ERANGE; - return; - } -- if (count > SUNMD5_MAX_ROUNDS) -+ if (count > SUNMD5_MAX_ROUNDS || nrbytes < 6 + 2) - { - errno = EINVAL; - return; -diff --git a/crypt.c b/crypt.c -index 405d9a3..753c649 100644 ---- a/crypt.c -+++ b/crypt.c -@@ -83,6 +83,17 @@ static const struct hashfn hash_algorithms[] = - HASH_ALGORITHM_TABLE_ENTRIES - }; - -+#if INCLUDE_des || INCLUDE_des_big -+static int -+is_des_salt_char (char c) -+{ -+ return ((c >= 'a' && c <= 'z') || -+ (c >= 'A' && c <= 'Z') || -+ (c >= '0' && c <= '9') || -+ c == '.' || c == '/'); -+} -+#endif -+ - static const struct hashfn * - get_hashfn (const char *setting) - { -@@ -98,7 +109,7 @@ get_hashfn (const char *setting) - else - { - if (setting[0] == '\0' || -- (setting[0] != '$' && setting[0] != '*')) -+ (is_des_salt_char (setting[0]) && is_des_salt_char (setting[1]))) - return h; - } - #endif -diff --git a/test-badsalt.c b/test-badsalt.c -index 6d57b14..b274337 100644 ---- a/test-badsalt.c -+++ b/test-badsalt.c -@@ -124,7 +124,13 @@ static const struct testcase testcases[] = - { "*MD5 (Sun, plain) invalid char", 14, "$md5$:xMeE.at$" }, - { "MD5 (Sun, rounds)", 25, "$md5,rounds=123$1xMeE.at$" }, - { "*MD5 (Sun, rounds) invalid char", 25, "$md5,rounds=123$:xMeE.at$" }, -- { "*MD5 (Sun, rounds) invalid rounds", 25, "$md5,rounds=:23$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds 1", 25, "$md5,rounds=:23$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds 2", 25, "$md5,rounds=12:$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds 3", 25, "$md5,rounds:123$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds 4", 22, "$md5,rounds=$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds 5", 23, "$md5,rounds=0$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds 6", 25, "$md5,rounds=012$1xMeE.at$" }, -+ { "*MD5 (Sun, rounds) invalid rounds 7", 32, "$md5,rounds=4294967295$1xMeE.at$" }, - #endif - #if INCLUDE_nthash - { "NTHASH (bare)", 3, "$3$" }, -@@ -133,33 +139,51 @@ static const struct testcase testcases[] = - #if INCLUDE_sha1 - { "HMAC-SHA1", 27, "$sha1$123$GGXpNqoJvglVTkGU$" }, - { "*HMAC-SHA1 invalid char", 27, "$sha1$123$:GXpNqoJvglVTkGU$" }, -- { "*HMAC-SHA1 invalid rounds", 27, "$sha1$:23$GGXpNqoJvglVTkGU$" }, -+ { "*HMAC-SHA1 invalid rounds 1", 27, "$sha1$:23$GGXpNqoJvglVTkGU$" }, -+ { "*HMAC-SHA1 invalid rounds 2", 27, "$sha1$12:$GGXpNqoJvglVTkGU$" }, -+ { "*HMAC-SHA1 invalid rounds 3", 27, "$sha1$12:$GGXpNqoJvglVTkGU$" }, - #endif - #if INCLUDE_sha256 - { "SHA-256 (plain)", 20, "$5$MJHnaAkegEVYHsFK$" }, - { "*SHA-256 (plain) invalid char", 20, "$5$:JHnaAkegEVYHsFK$" }, - { "SHA-256 (rounds)", 32, "$5$rounds=1000$MJHnaAkegEVYHsFK$" }, -- { "*SHA-256 (rounds) invalid rounds", 32, "$5$rounds=:000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds 1", 32, "$5$rounds=:000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds 2", 32, "$5$rounds=100:$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds 3", 32, "$5$rounds:1000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds 4", 28, "$5$rounds=$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds 5", 29, "$5$rounds=0$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds 6", 32, "$5$rounds=0100$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-256 (rounds) invalid rounds 7", 38, "$5$rounds=4294967295$MJHnaAkegEVYHsFK$" }, - #endif - #if INCLUDE_sha512 - { "SHA-512 (plain)", 20, "$6$MJHnaAkegEVYHsFK$" }, - { "*SHA-512 (plain) invalid char", 20, "$6$:JHnaAkegEVYHsFK$" }, - { "SHA-512 (rounds)", 32, "$6$rounds=1000$MJHnaAkegEVYHsFK$" }, -- { "*SHA-512 (rounds) invalid rounds", 32, "$6$rounds=:000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds 1", 32, "$6$rounds=:000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds 2", 32, "$6$rounds=100:$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds 3", 32, "$6$rounds:1000$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds 4", 28, "$6$rounds=$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds 5", 29, "$6$rounds=0$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds 6", 32, "$6$rounds=0100$MJHnaAkegEVYHsFK$" }, -+ { "*SHA-512 (rounds) invalid rounds 6", 38, "$6$rounds=4294967295$MJHnaAkegEVYHsFK$" }, - #endif - #if INCLUDE_bcrypt - { "bcrypt (a04)", 29, "$2a$04$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "*bcrypt (a04) invalid char", 29, "$2a$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -- { "*bcrypt (a04) invalid rounds", 29, "$2a$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (a04) invalid rounds 1", 29, "$2a$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (a04) invalid rounds 2", 29, "$2a$0:$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "bcrypt (b04)", 29, "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "*bcrypt (b04) invalid char", 29, "$2b$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -- { "*bcrypt (b04) invalid rounds", 29, "$2b$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (b04) invalid rounds 1", 29, "$2b$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (b04) invalid rounds 2", 29, "$2b$0:$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "bcrypt (x04)", 29, "$2x$04$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "*bcrypt (x04) invalid char", 29, "$2x$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -- { "*bcrypt (x04) invalid rounds", 29, "$2x$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (x04) invalid rounds 1", 29, "$2x$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (x04) invalid rounds 2", 29, "$2x$0:$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "bcrypt (y04)", 29, "$2y$04$UBVLHeMpJ/QQCv3XqJx8zO" }, - { "*bcrypt (y04) invalid char", 29, "$2y$04$:BVLHeMpJ/QQCv3XqJx8zO" }, -- { "*bcrypt (y04) invalid rounds", 29, "$2y$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (y04) invalid rounds 1", 29, "$2y$:4$UBVLHeMpJ/QQCv3XqJx8zO" }, -+ { "*bcrypt (y04) invalid rounds 2", 29, "$2y$0:$UBVLHeMpJ/QQCv3XqJx8zO" }, - #endif - }; - -diff --git a/test-badsetting.c b/test-badsetting.c -new file mode 100644 -index 0000000..ae2337b ---- /dev/null -+++ b/test-badsetting.c -@@ -0,0 +1,236 @@ -+/* Test rejection of ill-formed setting strings. -+ -+ Written by Zack Weinberg in 2017. -+ To the extent possible under law, Zack Weinberg has waived all -+ copyright and related or neighboring rights to this work. -+ -+ See https://creativecommons.org/publicdomain/zero/1.0/ for further -+ details. */ -+ -+#include "crypt-port.h" -+#include -+#include -+#include -+#include -+#include -+ -+/* Supply 64 bytes of "random" data to each gensalt call, for -+ determinism. */ -+static const char rbytes[] = -+ "yC8S8E7o+tmofM3L3DgKRwBy+RjWygAXIda7CAghZeXR9ZSl0UZh3kvt2XHg+aKo"; -+ -+struct testcase -+{ -+ const char *prefix; -+ unsigned long count; -+ int rbytes; /* 0 = use sizeof rbytes - 1 */ -+ int osize; /* 0 = use CRYPT_GENSALT_OUTPUT_SIZE */ -+}; -+ -+/* Note: because all of the test strings below are invalid settings, -+ they can all be tested unconditionally -- it doesn't matter whether -+ the specific hash algorithm that they are invalid for is actually -+ configured in. */ -+ -+static const struct testcase testcases[] = { -+ /* DES (traditional and/or bigcrypt) -- count is ignored */ -+ { "!a", 0, 0, 0 }, // invalid first character -+ { "a!", 0, 0, 0 }, // invalid second character -+ { "xx", 1, 0, 0 }, // doesn't accept variable counts -+ { "xx", 0, 1, 0 }, // inadequate rbytes -+ { "xx", 0, 0, 1 }, // inadequate osize -+ -+ -+ /* BSDi extended DES */ -+ { "_", 2, 0, 0 }, // even number -+ { "_", 16777217, 0, 0 }, // too large -+ { "_", 0, 2, 0 }, // inadequate rbytes -+ { "_", 0, 0, 4 }, // inadequate osize -+ -+ -+ /* MD5 (FreeBSD) */ -+ { "$1", 0, 0, 0 }, // truncated prefix -+ { "$1$", 1, 0, 0 }, // doesn't accept variable counts -+ { "$1$", 0, 2, 0 }, // inadequate rbytes -+ { "$1$", 0, 0, 4 }, // inadequate osize -+ -+ /* MD5 (Sun) */ -+ { "$m", 0, 0, 0 }, // truncated prefix -+ { "$md", 0, 0, 0 }, -+ { "$md5", 4294963200, 0, 0 }, // too large -+ { "$md5", 0, 2, 0 }, // inadequate rbytes -+ { "$md5", 0, 0, 4 }, // inadequate osize -+ -+ /* NTHASH */ -+ { "$3", 0, 0, 0 }, // truncated prefix -+ { "$3$", 0, 0, 4 }, // inadequate osize -+ -+ /* SHA1 */ -+ { "$s", 0, 0, 0 }, // truncated prefix -+ { "$sh", 0, 0, 0 }, -+ { "$sha", 0, 0, 0 }, -+ { "$sha1", 0, 2, 0 }, // inadequate rbytes -+ { "$sha1", 0, 0, 4 }, // inadequate osize -+ -+ /* SHA256 */ -+ { "$5", 0, 0, 0 }, // truncated prefix -+ { "$5$", 999, 0, 0 }, // too small -+ { "$5$", 1000000000, 0, 0 }, // too large -+ { "$5$", 0, 2, 0 }, // inadequate rbytes -+ { "$5$", 0, 0, 4 }, // inadequate osize -+ -+ /* SHA512 */ -+ { "$6", 0, 0, 0 }, // truncated prefix -+ { "$6$", 999, 0, 0 }, // too small -+ { "$6$", 1000000000, 0, 0 }, // too large -+ { "$6$", 0, 2, 0 }, // inadequate rbytes -+ { "$6$", 0, 0, 4 }, // inadequate osize -+ -+ /* bcrypt */ -+ { "$2", 0, 0, 0 }, // truncated prefix -+ { "$2a", 0, 0, 0 }, -+ { "$2b", 0, 0, 0 }, -+ { "$2x", 0, 0, 0 }, -+ { "$2y", 0, 0, 0 }, -+ { "$2b$", 3, 0, 0 }, // too small -+ { "$2b$", 32, 0, 0 }, // too large -+ { "$2b$", 0, 2, 0 }, // inadequate rbytes -+ { "$2b$", 0, 0, 4 }, // inadequate osize -+}; -+ -+static void -+print_escaped_string (const char *s) -+{ -+ putchar ('"'); -+ for (const char *p = s; *p; p++) -+ if (*p >= ' ' && *p <= '~') -+ { -+ if (*p == '\\' || *p == '\"') -+ putchar ('\\'); -+ putchar (*p); -+ } -+ else -+ printf ("\\x%02x", (unsigned int)(unsigned char)*p); -+ putchar ('"'); -+} -+ -+static bool error_occurred = false; -+static void -+report_error (const char *fn, const struct testcase *tc, -+ int err, const char *output) -+{ -+ error_occurred = true; -+ printf ("%s(", fn); -+ print_escaped_string (tc->prefix); -+ printf (", %lu, nrbytes=%d, osize=%d):\n", tc->count, -+ tc->rbytes > 0 ? tc->rbytes : (int) sizeof rbytes - 1, -+ tc->osize > 0 ? tc->osize : CRYPT_GENSALT_OUTPUT_SIZE); -+ -+ if (output) -+ { -+ if (err) -+ printf ("\toutput with errno = %s\n", strerror (err)); -+ printf ("\texpected NULL, got "); -+ print_escaped_string (output); -+ putchar ('\n'); -+ } -+ else if (err != (tc->osize > 0 ? ERANGE : EINVAL)) -+ printf ("\tno output with errno = %s\n", -+ err ? strerror (err) : "0"); -+ else -+ printf ("\tno output with errno = %s" -+ "(shouldn't have been called)\n", strerror (err)); -+ putchar ('\n'); -+} -+ -+static void -+test_one (const struct testcase *tc) -+{ -+ char obuf[CRYPT_GENSALT_OUTPUT_SIZE]; -+ char *s; -+ int nrbytes = tc->rbytes > 0 ? tc->rbytes : (int)(sizeof rbytes - 1); -+ int osize = tc->osize > 0 ? tc->osize : CRYPT_GENSALT_OUTPUT_SIZE; -+ -+ /* It is only possible to provide a variant osize to crypt_gensalt_rn. */ -+ if (tc->osize == 0) -+ { -+ errno = 0; -+ s = crypt_gensalt (tc->prefix, tc->count, rbytes, nrbytes); -+ if (s || errno != EINVAL) -+ report_error ("gensalt", tc, errno, s); -+ -+ errno = 0; -+ s = crypt_gensalt_ra (tc->prefix, tc->count, rbytes, nrbytes); -+ if (s || errno != EINVAL) -+ report_error ("gensalt_ra", tc, errno, s); -+ free (s); -+ } -+ -+ errno = 0; -+ s = crypt_gensalt_rn (tc->prefix, tc->count, rbytes, nrbytes, obuf, osize); -+ if (s || errno != (tc->osize > 0 ? ERANGE : EINVAL)) -+ report_error ("gensalt_rn", tc, errno, s); -+} -+ -+/* All single-character strings (except "_" when BSDi extended DES -+ is enabled) are invalid prefixes, either because the character -+ cannot be the first character of any valid prefix, or because the -+ string is too short. */ -+static void -+test_single_characters (void) -+{ -+ char s[2]; -+ struct testcase tc; -+ s[1] = '\0'; -+ tc.prefix = s; -+ tc.count = 0; -+ tc.rbytes = 0; -+ tc.osize = 0; -+ -+ for (int i = 1; i < 256; i++) -+ { -+#ifdef INCLUDE_des_xbsd -+ if (i == '_') continue; -+#endif -+ s[0] = (char)i; -+ test_one (&tc); -+ } -+} -+ -+/* '$' followed by any non-ASCII-isalnum character is also always -+ invalid. */ -+static void -+test_dollar_nonalphanum (void) -+{ -+ char s[3]; -+ struct testcase tc; -+ s[0] = '$'; -+ s[2] = '\0'; -+ tc.prefix = s; -+ tc.count = 0; -+ tc.rbytes = 0; -+ tc.osize = 0; -+ -+ for (int i = 1; i < 256; i++) -+ { -+ if (('0' >= i && i <= '9') || -+ ('A' >= i && i <= 'Z') || -+ ('a' >= i && i <= 'z')) -+ continue; -+ s[1] = (char)i; -+ test_one (&tc); -+ } -+} -+ -+int -+main(void) -+{ -+ test_single_characters(); -+ test_dollar_nonalphanum(); -+ -+ /* Hand-crafted arguments for each supported algorithm. */ -+ for (size_t i = 0; i < ARRAY_SIZE (testcases); i++) -+ test_one (&testcases[i]); -+ -+ return error_occurred; -+} -diff --git a/test-crypt-sha256.c b/test-crypt-sha256.c -index 7c42398..f0c7cb2 100644 ---- a/test-crypt-sha256.c -+++ b/test-crypt-sha256.c -@@ -21,11 +21,6 @@ static const struct - "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2." - "opqey6IcA" - }, -- { -- "$5$rounds=5000$toolongsaltstring", "This is just a test", -- "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8" -- "mGRcvxa5" -- }, - { - "$5$rounds=1400$anotherlongsaltstring", - "a very much longer text to encrypt. This one even stretches over more" -@@ -43,11 +38,6 @@ static const struct - "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/" - "cZKmF/wJvD" - }, -- { -- "$5$rounds=10$roundstoolow", "the minimum number is still observed", -- "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97" -- "2bIC" -- }, - }; - - #define ntests ARRAY_SIZE (tests) -diff --git a/test-crypt-sha512.c b/test-crypt-sha512.c -index c2a1973..798fb6a 100644 ---- a/test-crypt-sha512.c -+++ b/test-crypt-sha512.c -@@ -22,11 +22,6 @@ static const struct - "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb" - "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v." - }, -- { -- "$6$rounds=5000$toolongsaltstring", "This is just a test", -- "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ" -- "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" -- }, - { - "$6$rounds=1400$anotherlongsaltstring", - "a very much longer text to encrypt. This one even stretches over more" -@@ -45,11 +40,6 @@ static const struct - "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc" - "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1" - }, -- { -- "$6$rounds=10$roundstoolow", "the minimum number is still observed", -- "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x" -- "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." -- }, - }; - #define ntests ARRAY_SIZE (tests) - -diff --git a/test-gensalt.c b/test-gensalt.c -index 98923e5..6713387 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - static const char *const entropy[] = - { -@@ -25,6 +26,13 @@ static const char *const bsdi_expected_output[] = - "_J9..ZAFl", - "_J9..UqGB" - }; -+static const char *const bsdi_expected_output_r[] = -+{ -+ "_DT0.MJHn", -+ "_DT0.PKXc", -+ "_DT0.ZAFl", -+ "_DT0.UqGB" -+}; - #endif - #if INCLUDE_md5 - static const char *const md5_expected_output[] = -@@ -52,15 +60,29 @@ static const char *const sunmd5_expected_output[] = - "$md5,rounds=42259$3HtkHq/x$", - "$md5,rounds=73773$p.5e9AQf$", - }; -+static const char *const sunmd5_expected_output_r[] = -+{ -+ "$md5,rounds=4294920244$BPm.fm03$", -+ "$md5,rounds=4294937396$WKoucttX$", -+ "$md5,rounds=4294907154$3HtkHq/x$", -+ "$md5,rounds=4294938668$p.5e9AQf$", -+}; - #endif - #if INCLUDE_sha1 --static const char *const pbkdf_expected_output[] = -+static const char *const sha1_expected_output[] = - { - "$sha1$248488$ggu.H673kaZ5$", - "$sha1$248421$SWqudaxXA5L0$", - "$sha1$257243$RAtkIrDxEovH$", - "$sha1$250464$1j.eVxRfNAPO$", - }; -+static const char *const sha1_expected_output_r[] = -+{ -+ "$sha1$3643984551$ggu.H673kaZ5$", -+ "$sha1$4200450659$SWqudaxXA5L0$", -+ "$sha1$3946507480$RAtkIrDxEovH$", -+ "$sha1$3486175838$1j.eVxRfNAPO$", -+}; - #endif - #if INCLUDE_sha256 - static const char *const sha256_expected_output[] = -@@ -70,6 +92,13 @@ static const char *const sha256_expected_output[] = - "$5$ZAFlICwYRETzIzIj", - "$5$UqGBkVu01rurVZqg" - }; -+static const char *const sha256_expected_output_r[] = -+{ -+ "$5$rounds=10191$MJHnaAkegEVYHsFK", -+ "$5$rounds=10191$PKXc3hCOSyMqdaEQ", -+ "$5$rounds=10191$ZAFlICwYRETzIzIj", -+ "$5$rounds=10191$UqGBkVu01rurVZqg" -+}; - #endif - #if INCLUDE_sha512 - static const char *const sha512_expected_output[] = -@@ -79,6 +108,13 @@ static const char *const sha512_expected_output[] = - "$6$ZAFlICwYRETzIzIj", - "$6$UqGBkVu01rurVZqg" - }; -+static const char *const sha512_expected_output_r[] = -+{ -+ "$6$rounds=10191$MJHnaAkegEVYHsFK", -+ "$6$rounds=10191$PKXc3hCOSyMqdaEQ", -+ "$6$rounds=10191$ZAFlICwYRETzIzIj", -+ "$6$rounds=10191$UqGBkVu01rurVZqg" -+}; - #endif - #if INCLUDE_bcrypt - static const char *const bcrypt_a_expected_output[] = -@@ -117,41 +153,57 @@ struct testcase - const char *const *expected_output; - unsigned int expected_len; - unsigned int expected_auto_len; -+ unsigned long rounds; - }; - - static const struct testcase testcases[] = - { - #if INCLUDE_des || INCLUDE_des_big -- { "", des_expected_output, 2, 0 }, // DES -+ { "", des_expected_output, 2, 0, 0 }, -+ // DES doesn't have variable round count. - #endif - #if INCLUDE_des_xbsd -- { "_", bsdi_expected_output, 9, 0 }, // BSDi extended DES -+ { "_", bsdi_expected_output, 9, 0, 0 }, -+ { "_", bsdi_expected_output_r, 9, 0, 10191 }, - #endif - #if INCLUDE_md5 -- { "$1$", md5_expected_output, 11, 0 }, // MD5 -+ { "$1$", md5_expected_output, 11, 0, 0 }, -+ // MD5/BSD doesn't have variable round count. - #endif - #if INCLUDE_nthash -- { "$3$", nthash_expected_output, 29, 0 }, // NTHASH -+ { "$3$", nthash_expected_output, 29, 0, 0 }, -+ // NTHASH doesn't have variable round count. - #endif - #if INCLUDE_sunmd5 -- { "$md5", sunmd5_expected_output, 27, 0 }, // SUNMD5 -+ { "$md5", sunmd5_expected_output, 27, 0, 0 }, -+ // SHA1/PBKDF always emits a round count, but we need to test its -+ // behavior on very large inputs. (This number is the largest -+ // supported round count.) -+ { "$md5", sunmd5_expected_output_r, 32, 0, 4294963199 }, - #endif - #if INCLUDE_sha1 -- { "$sha1", pbkdf_expected_output, 26, 34 }, // PBKDF with SHA1 -+ { "$sha1", sha1_expected_output, 26, 34, 0 }, -+ // SHA1/PBKDF always emits a round count, but we need to test its -+ // behavior on very large inputs. (The behavior should be the -+ // same whether or not ULONG_MAX > UINT32_MAX.) -+ { "$sha1", sha1_expected_output_r, 30, 38, ULONG_MAX }, - #endif - #if INCLUDE_sha256 -- { "$5$", sha256_expected_output, 19, 0 }, // SHA-2-256 -+ { "$5$", sha256_expected_output, 19, 0, 0 }, -+ { "$5$", sha256_expected_output_r, 32, 0, 10191 }, - #endif - #if INCLUDE_sha512 -- { "$6$", sha512_expected_output, 19, 0 }, // SHA-2-512 -+ { "$6$", sha512_expected_output, 19, 0, 0 }, -+ { "$6$", sha512_expected_output_r, 32, 0, 10191 }, - #endif - #if INCLUDE_bcrypt -- { "$2a$", bcrypt_a_expected_output, 29, 0 }, // bcrypt mode A -- { "$2b$", bcrypt_b_expected_output, 29, 0 }, // bcrypt mode B -- { "$2x$", bcrypt_x_expected_output, 29, 0 }, // bcrypt mode X -- { "$2y$", bcrypt_y_expected_output, 29, 0 }, // bcrypt mode Y -+ { "$2a$", bcrypt_a_expected_output, 29, 0, 0 }, -+ { "$2b$", bcrypt_b_expected_output, 29, 0, 0 }, -+ { "$2x$", bcrypt_x_expected_output, 29, 0, 0 }, -+ { "$2y$", bcrypt_y_expected_output, 29, 0, 0 }, -+ // bcrypt gensalt always emits a round count. - #endif -- { 0, 0, 0, 0 } -+ { 0, 0, 0, 0, 0 } - }; - - int -@@ -169,7 +221,7 @@ main (void) - for (ent = 0; ent < ARRAY_SIZE (entropy); ent++) - { - XCRYPT_SECURE_MEMSET (output, CRYPT_GENSALT_OUTPUT_SIZE); -- char *salt = crypt_gensalt_rn (tcase->prefix, 0, -+ char *salt = crypt_gensalt_rn (tcase->prefix, tcase->rounds, - entropy[ent], 16, - output, CRYPT_GENSALT_OUTPUT_SIZE); - if (salt == 0) - -From 4f71018701bf54fb9891cc94d8d268f46ed82e62 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Wed, 11 Jul 2018 21:53:54 -0400 -Subject: [PATCH 29/41] Fix test-badsetting when not all hashes are enabled. - -It turns out I was wrong to think that we could safely leave the -subtests for excluded hashes enabled, because you get a slightly -different error in some cases (EINVAL instead of ERANGE). Instead, -for excluded hashes, check that a *correct* gensalt invocation will -still fail. ---- - test-badsetting.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 44 insertions(+), 7 deletions(-) - -diff --git a/test-badsetting.c b/test-badsetting.c -index ae2337b..d6abe71 100644 ---- a/test-badsetting.c -+++ b/test-badsetting.c -@@ -27,66 +27,97 @@ struct testcase - int osize; /* 0 = use CRYPT_GENSALT_OUTPUT_SIZE */ - }; - --/* Note: because all of the test strings below are invalid settings, -- they can all be tested unconditionally -- it doesn't matter whether -- the specific hash algorithm that they are invalid for is actually -- configured in. */ -- -+/* For each included hash, test malformed versions of its prefix -+ and invalid combinations of other arguments to gensalt. -+ For each excluded hash, test that a correct gensalt invocation -+ will still be rejected. */ - static const struct testcase testcases[] = { - /* DES (traditional and/or bigcrypt) -- count is ignored */ -+#if INCLUDE_des || INCLUDE_des_big - { "!a", 0, 0, 0 }, // invalid first character - { "a!", 0, 0, 0 }, // invalid second character - { "xx", 1, 0, 0 }, // doesn't accept variable counts - { "xx", 0, 1, 0 }, // inadequate rbytes - { "xx", 0, 0, 1 }, // inadequate osize -- -+#else -+ { "", 0, 0, 0 }, -+ { "xx", 0, 0, 0 }, -+#endif - - /* BSDi extended DES */ -+#if INCLUDE_des_xbsd - { "_", 2, 0, 0 }, // even number - { "_", 16777217, 0, 0 }, // too large - { "_", 0, 2, 0 }, // inadequate rbytes - { "_", 0, 0, 4 }, // inadequate osize -- -+#else -+ { "_", 0, 0, 0 }, -+#endif - - /* MD5 (FreeBSD) */ -+#if INCLUDE_md5 - { "$1", 0, 0, 0 }, // truncated prefix - { "$1$", 1, 0, 0 }, // doesn't accept variable counts - { "$1$", 0, 2, 0 }, // inadequate rbytes - { "$1$", 0, 0, 4 }, // inadequate osize -+#else -+ { "$1$", 0, 0, 0 }, -+#endif - - /* MD5 (Sun) */ -+#if INCLUDE_sunmd5 - { "$m", 0, 0, 0 }, // truncated prefix - { "$md", 0, 0, 0 }, - { "$md5", 4294963200, 0, 0 }, // too large - { "$md5", 0, 2, 0 }, // inadequate rbytes - { "$md5", 0, 0, 4 }, // inadequate osize -+#else -+ { "$md5", 0, 0, 0 }, -+#endif - - /* NTHASH */ -+#if INCLUDE_nthash - { "$3", 0, 0, 0 }, // truncated prefix - { "$3$", 0, 0, 4 }, // inadequate osize -+#else -+ { "$3$", 0, 0, 0 }, -+#endif - - /* SHA1 */ -+#if INCLUDE_sha1 - { "$s", 0, 0, 0 }, // truncated prefix - { "$sh", 0, 0, 0 }, - { "$sha", 0, 0, 0 }, - { "$sha1", 0, 2, 0 }, // inadequate rbytes - { "$sha1", 0, 0, 4 }, // inadequate osize -+#else -+ { "$sha1", 0, 0, 0 }, -+#endif - - /* SHA256 */ -+#if INCLUDE_sha256 - { "$5", 0, 0, 0 }, // truncated prefix - { "$5$", 999, 0, 0 }, // too small - { "$5$", 1000000000, 0, 0 }, // too large - { "$5$", 0, 2, 0 }, // inadequate rbytes - { "$5$", 0, 0, 4 }, // inadequate osize -+#else -+ { "$5$", 0, 0, 0 }, -+#endif - - /* SHA512 */ -+#if INCLUDE_sha512 - { "$6", 0, 0, 0 }, // truncated prefix - { "$6$", 999, 0, 0 }, // too small - { "$6$", 1000000000, 0, 0 }, // too large - { "$6$", 0, 2, 0 }, // inadequate rbytes - { "$6$", 0, 0, 4 }, // inadequate osize -+#else -+ { "$6$", 0, 0, 0 }, -+#endif - - /* bcrypt */ -+#if INCLUDE_bcrypt - { "$2", 0, 0, 0 }, // truncated prefix - { "$2a", 0, 0, 0 }, - { "$2b", 0, 0, 0 }, -@@ -96,6 +127,12 @@ static const struct testcase testcases[] = { - { "$2b$", 32, 0, 0 }, // too large - { "$2b$", 0, 2, 0 }, // inadequate rbytes - { "$2b$", 0, 0, 4 }, // inadequate osize -+#else -+ { "$2a$", 0, 0, 0 }, -+ { "$2b$", 0, 0, 0 }, -+ { "$2x$", 0, 0, 0 }, -+ { "$2y$", 0, 0, 0 }, -+#endif - }; - - static void - -From b9064279d0d73e7d1f0ce3de3d52c31ed7a8ca2e Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Thu, 12 Jul 2018 12:21:44 -0400 -Subject: [PATCH 30/41] crypt.5: Add docs for SHA1, MD5/Sun, NTHASH. - -Also tighten up the wording in a couple other places and fix a bug -that was making the .hash macro not do what it was supposed to for -the DES-based hashes. ---- - crypt.5 | 114 +++++++++++++++++++++++++++++++++++++++------------------------- - 1 file changed, 70 insertions(+), 44 deletions(-) - -diff --git a/crypt.5 b/crypt.5 -index f79dd3d..5db9c92 100644 ---- a/crypt.5 -+++ b/crypt.5 -@@ -139,8 +139,7 @@ and does not show the division into prefix, options, salt, and hash. - .TP - .B Hash size - \\$6 bits --.ie "\\$5"\\$6" --.el (effectively \\$5) -+.if !"\\$5"\\$6" (effectively \\$5) - .TP - .B Salt size - \\$7 bits -@@ -159,66 +158,76 @@ Originally developed by Niels Provos and David Mazieres for OpenBSD - and also supported on recent versions of FreeBSD and NetBSD, - on Solaris 10 and newer, and on several GNU/*/Linux distributions. - Recommended for new password hashes. --.hash "$2b$" "\e$2[abxy]\e$[0-9]{2}\e$[./A-Za-z0-9]{53}" 72 8 "" 184 128 "4 to 31 (logarithmic)" -+.hash "$2b$" "\e$2[abxy]\e$[0-9]{2}\e$[./A-Za-z0-9]{53}" 72 8 184 184 128 "4 to 31 (logarithmic)" - .PP --bcrypt hashes originally used the "$2a$" prefix. --However, in 2011 an implementation bug was discovered in crypt_blowfish --(versions up to 1.0.4 inclusive) affecting handling of password characters with --the 8th bit set. --Besides fixing the bug, --to provide for upgrade strategies for existing systems, two new prefixes were --introduced: "$2x$", which fully re-introduces the bug, and "$2y$", which --guarantees correct handling of both 7- and 8-bit characters. --OpenBSD 5.5 introduced the "$2b$" prefix for behavior that exactly matches --crypt_blowfish's "$2y$", and current crypt_blowfish supports it as well. --Unfortunately, the behavior of "$2a$" on password characters with the 8th bit --set has to be considered system-specific. --When generating new password hashes, the "$2b$" or "$2y$" prefix should be used. --(If such hashes ever need to be migrated to a system that does not yet support --these new prefixes, the prefix in migrated copies of the already-generated --hashes may be changed to "$2a$".) -+The alternative prefix "$2y$" is equivalent to "$2b$". -+It exists for historical reasons only. -+The alternative prefixes "$2a$" and "$2x$" -+provide bug-compatibility with crypt_blowfish 1.0.4 and earlier, -+which incorrectly processed characters with the 8th bit set. - .PP - .ti -4 - .B SHA-2-512 - .br --A hash based on SHA-2 with 512-bit output, originally developed by --Ulrich Drepper for GNU libc. -+A hash based on SHA-2 with 512-bit output, -+originally developed by Ulrich Drepper for GNU libc. - Supported on Linux but not common elsewhere. - Acceptable for new password hashes. --The default CPU time cost parameter is 5000, which is too low for --modern hardware. -+The default CPU time cost parameter is 5000, -+which is too low for modern hardware. - .br --.hash "$6$" "\e$6\e$(rounds=[0-9]+\e$)?[^$]{1,16}\e$[./0-9A-Za-z]{86}" unlimited 8 512 512 "6 to 96" "1000 to 999,999,999" -+.hash "$6$" "\e$6\e$(rounds=[1-9][0-9]+\e$)?[./0-9A-Za-z]{1,16}\e$[./0-9A-Za-z]{86}" unlimited 8 512 512 "6 to 96" "1000 to 999,999,999" - .PP - .ti -4 - .B SHA-2-256 - .br --A hash based on SHA-2 with 256-bit output, originally developed by --Ulrich Drepper for GNU libc. -+A hash based on SHA-2 with 256-bit output, -+originally developed by Ulrich Drepper for GNU libc. - Supported on Linux but not common elsewhere. - Acceptable for new password hashes. --The default CPU time cost parameter is 5000, which is too low for --modern hardware. -+The default CPU time cost parameter is 5000, -+which is too low for modern hardware. - .br --.hash "$5$" "\e$5\e$(rounds=[0-9]+\e$)?[^$]{1,16}\e$[./0-9A-Za-z]{43}" unlimited 8 256 256 "6 to 96" "1000 to 999,999,999" -+.hash "$5$" "\e$5\e$(rounds=[1-9][0-9]+\e$)?[./0-9A-Za-z]{1,16}\e$[./0-9A-Za-z]{43}" unlimited 8 256 256 "6 to 96" "1000 to 999,999,999" - .PP - .ti -4 --.B MD5 -+.B SHA-1 -+.br -+A hash based on HMAC-SHA1. -+Originally developed by Simon Gerraty for NetBSD. -+Not as weak as the DES-based hashes below, -+but SHA1 is so cheap on modern hardware -+that it should not be used for new hashes. -+.hash "$sha1" "\e$sha1\e$[1-9][0-9]+\e$[./0-9A-Za-z]{1,64}\e$[./0-9A-Za-z]{8,64}[./0-9A-Za-z]{32}" unlimited 8 160 160 "6 to 384" "1 to 4,294,967,295" -+.PP -+.ti -4 -+.B MD5 (Sun) -+.br -+A hash based on the MD5 algorithm, -+with additional cleverness to make precomputation difficult, -+originally developed by Alec David Muffet for Solaris. -+Not adopted elsewhere, to our knowledge. -+Not as weak as the DES-based hashes below, -+but MD5 is so cheap on modern hardware -+that it should not be used for new hashes. -+.hash "$md5" "\e$md5(,rounds=[1-9][0-9]+)?\e$[./0-9A-Za-z]{8}\e${1,2}[./0-9A-Za-z]{22}" unlimited 8 128 128 48 "4096 to 4,294,963,199" -+.PP -+.ti -4 -+.B MD5 (FreeBSD) - .br - A hash based on the MD5 algorithm, originally developed by - Poul-Henning Kamp for FreeBSD. - Supported on most free Unixes and newer versions of Solaris. - Not as weak as the DES-based hashes below, --but due to the weak cryptographic primitive at its heart --and the fixed CPU time cost --(which is already much too low) --it should not be used for new hashes. -+but MD5 is so cheap on modern hardware -+that it should not be used for new hashes. -+CPU time cost is not adjustable. - .hash "$1$" "\e$1\e$[^$]{1,8}\e$[./0-9A-Za-z]{22}" unlimited 8 128 128 "6 to 48" 1000 - .PP - .ti -4 - .B BSDI extended DES - .br --This is another weak extension of traditional DES, -+A weak extension of traditional DES, - which eliminates the length limit, - increases the salt size, - and makes the time cost tunable. -@@ -227,30 +236,47 @@ and is also available on at least NetBSD, OpenBSD, and FreeBSD - due to the use of David Burren's FreeSec library. - It is better than bigcrypt and traditional DES, - but still should not be used for new hashes. --.hash _ "_[./0-9A-Za-z]{19}" unlimited 7 56 64 24 "1 to 2**24-1 (must be odd)" -+.hash _ "_[./0-9A-Za-z]{19}" unlimited 7 56 64 24 "1 to 16,777,215 (must be odd)" - .PP - .ti -4 - .B bigcrypt - .br --This is a weak extension of traditional DES, -+A weak extension of traditional DES, - available on some System V-derived Unixes. --All it does is raise the length limit from 8 to 128 characters. -+All it does is raise the length limit from 8 to 128 characters, -+and it does this in a crude way that allows attackers to -+guess chunks of a long passphrase in parallel. - It should not be used for new hashes. - .hash "" "[./0-9A-Za-z]{13,178}" 128 7 "up to 896" "up to 1024" 12 25 - .PP - .ti -4 - .B Traditional DES-based - .br --This method is supported by almost all implementations of --.BR crypt . --Because it is based on a weak cipher primitive, -+The original hashing method from Unix V7, based on the DES block cipher. -+Because DES is cheap on modern hardware, - because there are only 4096 possible salts and 2**56 possible hashes, --and especially because it truncates passphrases to 8 characters, --it no longer offers adequate security for new passphrases. -+and because it truncates passphrases to 8 characters, -+it is feasible to discover -+.I any -+passphrase hashed with this method. - It should only be used if you absolutely have to generate hashes - that will work on an old operating system that supports nothing else. - .hash "" "[./0-9A-Za-z]{13}" 8 7 56 64 12 25 -- -+.PP -+.ti -4 -+.B NTHASH -+.br -+The hashing method used for network authentication -+in some versions of the SMB/CIFS protocol. -+Available, for cross-compatibility's sake, on FreeBSD. -+Based on MD4. -+Has no salt or tunable cost parameter. -+Like traditional DES, it is so weak that -+.I any -+passphrase hashed with this method is guessable. -+It should only be used if you absolutely have to generate hashes -+that will work on an old operating system that supports nothing else. -+.hash "$3$" "\e$3\e$\e$[0-9a-f]{32}" unlimited 8 256 256 0 1 - .SH SEE ALSO - .BR crypt (3), - .BR crypt_rn (3), - -From 77461c03422ce1f5829b0180e68c4bdbf914956c Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Thu, 12 Jul 2018 12:23:59 -0400 -Subject: [PATCH 31/41] Add two more test programs to .gitignore. - ---- - .gitignore | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/.gitignore b/.gitignore -index bb7f15c..16488f3 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -54,6 +54,7 @@ - /test-alg-sha256 - /test-alg-sha512 - /test-badsalt -+/test-badsetting - /test-bigcrypt - /test-byteorder - /test-crypt-bcrypt -@@ -67,6 +68,7 @@ - /test-des-obsolete - /test-des-obsolete_r - /test-gensalt -+/test-short-outbuf - - # backup-files - - -From 9f728b79718a8e8b371f48b75592beed638f9c2b Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Thu, 12 Jul 2018 12:24:46 -0400 -Subject: [PATCH 32/41] test-badsetting.c: correct "Written by" year. - ---- - test-badsetting.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/test-badsetting.c b/test-badsetting.c -index d6abe71..665e830 100644 ---- a/test-badsetting.c -+++ b/test-badsetting.c -@@ -1,6 +1,6 @@ - /* Test rejection of ill-formed setting strings. - -- Written by Zack Weinberg in 2017. -+ Written by Zack Weinberg in 2018. - To the extent possible under law, Zack Weinberg has waived all - copyright and related or neighboring rights to this work. - - -From b3ee64bf08082367ea2116ea1fb2007e1a2896cd Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Thu, 12 Jul 2018 12:25:12 -0400 -Subject: [PATCH 33/41] Add tests for get_random_bytes. - -It turns out not to be *that* hard to exercise the fallback logic in -get_random_bytes, thanks to GNU ld's --wrap feature. There is also -some basic black-box testing of the get_random_bytes interface. - -The change to randombytes.c itself ensures 100% predictable behavior -if get_random_bytes should ever be called with buflen zero. ---- - .gitignore | 2 + - Makefile.am | 10 +- - configure.ac | 1 + - m4/zw_ld_wrap.m4 | 47 ++++++++ - randombytes.c | 2 + - test-getrandom-fallbacks.c | 282 +++++++++++++++++++++++++++++++++++++++++++++ - test-getrandom-interface.c | 211 +++++++++++++++++++++++++++++++++ - 7 files changed, 554 insertions(+), 1 deletion(-) - create mode 100644 m4/zw_ld_wrap.m4 - create mode 100644 test-getrandom-fallbacks.c - create mode 100644 test-getrandom-interface.c - -diff --git a/.gitignore b/.gitignore -index 16488f3..06ee727 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -68,6 +68,8 @@ - /test-des-obsolete - /test-des-obsolete_r - /test-gensalt -+/test-getrandom-fallbacks -+/test-getrandom-interface - /test-short-outbuf - - # backup-files -diff --git a/Makefile.am b/Makefile.am -index 51cba76..f99f842 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -127,7 +127,8 @@ check_PROGRAMS = \ - test-crypt-pbkdf1-sha1 test-crypt-sha256 test-crypt-sha512 \ - test-crypt-sunmd5 \ - test-byteorder test-badsalt test-badsetting test-gensalt \ -- test-short-outbuf -+ test-short-outbuf \ -+ test-getrandom-interface test-getrandom-fallbacks - - if ENABLE_OBSOLETE_API - libcrypt_la_SOURCES += crypt-des-obsolete.c -@@ -183,6 +184,13 @@ test_alg_sha1_LDADD = alg-sha1.lo - test_alg_sha256_LDADD = alg-sha256.lo - test_alg_sha512_LDADD = alg-sha512.lo - -+test_getrandom_interface_LDADD = randombytes.lo -+test_getrandom_fallbacks_LDADD = randombytes.lo -+if HAVE_LD_WRAP -+test_getrandom_fallbacks_LDFLAGS = \ -+ -Wl,--wrap,getentropy -Wl,--wrap,getrandom -Wl,--wrap,syscall \ -+ -Wl,--wrap,open -Wl,--wrap,read -Wl,--wrap,close -+endif - - # Every object file depends on crypt-symbol-vers.h and crypt-hashes.h, - # which are generated files, so automatic dependency generation is not -diff --git a/configure.ac b/configure.ac -index 119f171..274c16a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -137,6 +137,7 @@ zw_C_ALIGNAS - zw_C_ALIGNOF - zw_C_MAX_ALIGN_T - zw_C_STATIC_ASSERT -+zw_PROG_LD_WRAP - - # Checks for library functions. - AC_CHECK_FUNCS_ONCE([ -diff --git a/m4/zw_ld_wrap.m4 b/m4/zw_ld_wrap.m4 -new file mode 100644 -index 0000000..87b22e7 ---- /dev/null -+++ b/m4/zw_ld_wrap.m4 -@@ -0,0 +1,47 @@ -+dnl Written by Zack Weinberg in 2018. -+dnl To the extent possible under law, Zack Weinberg has waived all -+dnl copyright and related or neighboring rights to this work. -+dnl -+dnl See https://creativecommons.org/publicdomain/zero/1.0/ for further -+dnl details. -+dnl -+dnl Find out whether ld --wrap is supported. -+AC_DEFUN([zw_PROG_LD_WRAP], -+ [AC_REQUIRE([AC_PROG_CC]) -+ AC_CACHE_CHECK([for ld --wrap], [zw_cv_prog_ld_wrap], -+ [save_LDFLAGS="$LDFLAGS" -+ save_LIBS="$LIBS" -+ LDFLAGS="" -+ LIBS="" -+ AC_COMPILE_IFELSE( -+ [AC_LANG_SOURCE([[ -+ extern void bar(void); -+ void foo(void) { bar(); } -+ ]])], -+ [mv conftest.$OBJEXT conftest2.$OBJEXT -+ LDFLAGS="-Wl,--wrap,bar" -+ LIBS="conftest2.$OBJEXT" -+ AC_LINK_IFELSE( -+ [AC_LANG_PROGRAM([[ -+ extern void foo(void); -+ void __wrap_bar(void) {} -+ ]], [[ -+ foo(); -+ ]])], -+ [zw_cv_prog_ld_wrap=yes], -+ [zw_cv_prog_ld_wrap=no]) -+ rm -f conftest2.$OBJEXT -+ ], -+ [zw_cv_prog_ld_wrap=no]) -+ LDFLAGS="$save_LDFLAGS" -+ LIBS="$save_LIBS"]) -+ if test x$zw_cv_prog_ld_wrap = xyes; then -+ have_ld_wrap=yes -+ AC_DEFINE([HAVE_LD_WRAP], 1, -+ [Define to 1 if -Wl,--wrap,SYMBOL can be used to intercept -+ calls to SYMBOL at link time.]) -+ else -+ have_ld_wrap=no -+ fi -+ AM_CONDITIONAL([HAVE_LD_WRAP], [test $have_ld_wrap = yes]) -+]) -diff --git a/randombytes.c b/randombytes.c -index 5053525..8d95dcc 100644 ---- a/randombytes.c -+++ b/randombytes.c -@@ -61,6 +61,8 @@ - bool - get_random_bytes(void *buf, size_t buflen) - { -+ if (buflen == 0) -+ return true; - if (buflen > 256) - { - errno = EIO; -diff --git a/test-getrandom-fallbacks.c b/test-getrandom-fallbacks.c -new file mode 100644 -index 0000000..8cbab5f ---- /dev/null -+++ b/test-getrandom-fallbacks.c -@@ -0,0 +1,282 @@ -+/* Test the fallback logic in get_random_bytes. -+ -+ Written by Zack Weinberg in 2018. -+ To the extent possible under law, Zack Weinberg has waived all -+ copyright and related or neighboring rights to this work. -+ -+ See https://creativecommons.org/publicdomain/zero/1.0/ for further -+ details. */ -+ -+#include "crypt-port.h" -+#include "crypt-private.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef HAVE_FCNTL_H -+#include -+#endif -+#if defined HAVE_SYS_SYSCALL_H -+#include -+#endif -+#ifdef HAVE_SYS_STAT_H -+#include -+#endif -+#ifdef HAVE_UNISTD_H -+#include -+#endif -+ -+/* If arc4random_buf is available, all of the fallback logic is compiled -+ out and this test is unnecessary. If ld --wrap is not available this -+ test will not work. */ -+#if defined HAVE_ARC4RANDOM_BUF || !defined HAVE_LD_WRAP -+ -+int -+main (void) -+{ -+ return 77; -+} -+ -+#else -+ -+/* All of the mock system primitives below fill in their buffer with -+ repeats of these bytes, so we can tell where the data came from. */ -+#define MOCK_getentropy 'e' -+#define MOCK_getrandom 'r' -+#define MOCK_sys_getentropy 'E' -+#define MOCK_sys_getrandom 'R' -+#define MOCK_urandom 'u' -+ -+#ifdef HAVE_GETENTROPY -+static bool getentropy_should_fail = false; -+extern int __wrap_getentropy (void *, size_t); -+int -+__wrap_getentropy (void *buf, size_t buflen) -+{ -+ if (getentropy_should_fail) -+ { -+ errno = ENOSYS; -+ return -1; -+ } -+ else -+ { -+ memset (buf, MOCK_getentropy, buflen); -+ return 0; -+ } -+} -+#endif -+ -+#ifdef HAVE_GETRANDOM -+static bool getrandom_should_fail = false; -+extern ssize_t __wrap_getrandom (void *, size_t, unsigned int); -+ssize_t -+__wrap_getrandom (void *buf, size_t buflen, unsigned int ARG_UNUSED(flags)) -+{ -+ if (getrandom_should_fail) -+ { -+ errno = ENOSYS; -+ return -1; -+ } -+ else -+ { -+ buflen = MIN (buflen, SSIZE_MAX); -+ memset (buf, MOCK_getrandom, buflen); -+ return (ssize_t)buflen; -+ } -+} -+#endif -+ -+#ifdef HAVE_SYSCALL -+#ifdef SYS_getentropy -+static bool sys_getentropy_should_fail = false; -+#endif -+#ifdef SYS_getrandom -+static bool sys_getrandom_should_fail = false; -+#endif -+static bool other_syscalls = false; -+extern long __wrap_syscall (long, ...); -+long -+__wrap_syscall(long number, ...) -+{ -+#ifdef SYS_getentropy -+ if (number == SYS_getentropy) -+ { -+ if (sys_getentropy_should_fail) -+ { -+ errno = ENOSYS; -+ return -1; -+ } -+ else -+ { -+ va_list ap; -+ va_start (ap, number); -+ void *buf = va_arg (ap, void *); -+ size_t buflen = va_arg (ap, size_t); -+ va_end (ap); -+ memset (buf, MOCK_sys_getentropy, buflen); -+ return 0; -+ } -+ } -+#endif -+#ifdef SYS_getrandom -+ if (number == SYS_getrandom) -+ { -+ if (sys_getrandom_should_fail) -+ { -+ errno = ENOSYS; -+ return -1; -+ } -+ else -+ { -+ va_list ap; -+ va_start (ap, number); -+ void *buf = va_arg (ap, void *); -+ size_t buflen = va_arg (ap, size_t); -+ buflen = MIN (buflen, SSIZE_MAX); -+ memset (buf, MOCK_sys_getrandom, buflen); -+ return (ssize_t)buflen; -+ } -+ } -+#endif -+ /* There is no vsyscall. We just have to hope nobody in this test -+ program wants to use syscall() for anything else. */ -+ other_syscalls = true; -+ fprintf (stderr, "ERROR: unexpected syscall(%ld)\n", number); -+ errno = ENOSYS; -+ return -1; -+} -+#endif /* HAVE_SYSCALL */ -+ -+/* It is not possible to hit both of the code paths that can set the -+ "/dev/urandom doesn't work" flag in a single test program, because -+ there's no way to _clear_ that flag again. This test chooses to -+ exercise the read-failure path, not the open-failure path. */ -+#if defined HAVE_SYS_STAT_H && defined HAVE_FCNTL_H && defined HAVE_UNISTD_H -+static bool urandom_should_fail = false; -+static int urandom_fd = -1; -+extern int __wrap_open (const char *, int, mode_t); -+extern int __real_open (const char *, int, mode_t); -+int -+__wrap_open (const char *path, int flags, mode_t mode) -+{ -+ int ret = __real_open (path, flags, mode); -+ if (ret == -1) -+ return ret; -+ if (!strcmp (path, "/dev/urandom")) -+ urandom_fd = ret; -+ return ret; -+} -+ -+extern int __wrap_close (int); -+extern int __real_close (int); -+int -+__wrap_close (int fd) -+{ -+ if (fd == urandom_fd) -+ urandom_fd = -1; -+ return __real_close (fd); -+} -+ -+extern ssize_t __wrap_read (int, void *, size_t); -+extern ssize_t __real_read (int, void *, size_t); -+ssize_t -+__wrap_read (int fd, void *buf, size_t count) -+{ -+ if (fd == urandom_fd) -+ { -+ if (urandom_should_fail) -+ { -+ errno = ENOSYS; -+ return -1; -+ } -+ else -+ { -+ count = MIN (count, SSIZE_MAX); -+ memset (buf, MOCK_urandom, count); -+ return (ssize_t)count; -+ } -+ } -+ else -+ return __real_read (fd, buf, count); -+} -+ -+#endif -+ -+struct subtest -+{ -+ const char *what; -+ bool *make_fail; -+ char expected; -+}; -+const struct subtest subtests[] = { -+ { "initial", 0, 'x' }, -+ -+#ifdef HAVE_GETENTROPY -+ { "getentropy", &getentropy_should_fail, MOCK_getentropy }, -+#endif -+#ifdef HAVE_GETRANDOM -+ { "getrandom", &getrandom_should_fail, MOCK_getrandom }, -+#endif -+ -+#ifdef HAVE_SYSCALL -+#ifdef SYS_getentropy -+ { "sys_getentropy", &sys_getentropy_should_fail, MOCK_sys_getentropy }, -+#endif -+#ifdef SYS_getrandom -+ { "sys_getrandom", &sys_getrandom_should_fail, MOCK_sys_getrandom }, -+#endif -+#endif -+ -+#if defined HAVE_SYS_STAT_H && defined HAVE_FCNTL_H && defined HAVE_UNISTD_H -+ { "/dev/urandom", &urandom_should_fail, MOCK_urandom }, -+#endif -+ -+ { "final", 0, 0 } -+}; -+ -+int -+main (void) -+{ -+ char buf[257]; -+ char expected[2] = { 0, 0 }; -+ memset (buf, 'x', sizeof buf - 1); -+ buf[256] = '\0'; -+ bool failed = false; -+ const struct subtest *s; -+ -+ for (s = subtests; s->expected;) -+ { -+ expected[0] = s->expected; -+ if (strspn (buf, expected) != 256) -+ { -+ printf ("FAIL: %s: buffer not filled with '%c'\n", -+ s->what, s->expected); -+ failed = true; -+ } -+ else -+ printf ("ok: %s (output)\n", s->what); -+ -+ if (s->make_fail) -+ *(s->make_fail) = true; -+ s++; -+ -+ bool r = get_random_bytes (buf, sizeof buf - 1); -+ if ((s->expected && !r) || (!s->expected && r)) -+ { -+ printf ("FAIL: %s: get_random_bytes: %s\n", -+ s->what, strerror (errno)); -+ failed = true; -+ } -+ else -+ printf ("ok: %s (return)\n", s->what); -+ } -+#if HAVE_SYSCALL -+ failed |= other_syscalls; -+#endif -+ return failed; -+} -+ -+#endif -diff --git a/test-getrandom-interface.c b/test-getrandom-interface.c -new file mode 100644 -index 0000000..16df6d0 ---- /dev/null -+++ b/test-getrandom-interface.c -@@ -0,0 +1,211 @@ -+/* Test the exposed interface of get_random_bytes. -+ -+ Written by Zack Weinberg in 2018. -+ To the extent possible under law, Zack Weinberg has waived all -+ copyright and related or neighboring rights to this work. -+ -+ See https://creativecommons.org/publicdomain/zero/1.0/ for further -+ details. */ -+ -+#include "crypt-port.h" -+#include "crypt-private.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static bool error_occurred; -+ -+/* Note: both of the following test functions expect PAGE to point to -+ PAGESIZE bytes of read-write memory followed by another PAGESIZE -+ bytes of unwritable memory. Both functions also assume that -+ PAGESIZE is greater than or equal to 256. */ -+ -+static void -+test_basic (char *page, size_t pagesize) -+{ -+ printf ("Testing basic functionality...\n"); -+ -+ // A request for zero bytes should succeed, and should not touch the -+ // output buffer. -+ if (!get_random_bytes (page + pagesize, 0)) -+ { -+ printf ("ERROR: get_random_bytes(0) = %s\n", strerror (errno)); -+ error_occurred = 1; -+ } -+ else -+ printf ("ok: get_random_bytes(0)\n"); -+ -+ // A request for 257 bytes should fail, and should not touch the -+ // output buffer. -+ if (get_random_bytes (page + pagesize, 257)) -+ { -+ printf ("ERROR: get_random_bytes(257) succeeded\n"); -+ error_occurred = 1; -+ } -+ else if (errno != EIO) -+ { -+ printf ("ERROR: get_random_bytes(257) = %s (expected: %s)\n", -+ strerror (errno), strerror (EIO)); -+ error_occurred = 1; -+ } -+ else -+ printf ("ok: get_random_bytes(257)\n"); -+ -+ // A request for five bytes should succeed, and should not write -+ // past the end of the buffer. (We use an odd, prime number here to -+ // catch implementations that might write e.g. four or eight bytes -+ // at once.) -+ if (!get_random_bytes (page + pagesize - 5, 5)) -+ { -+ printf ("ERROR: get_random_bytes(5) = %s\n", strerror (errno)); -+ error_occurred = 1; -+ } -+ else -+ printf ("ok: get_random_bytes(5)\n"); -+ -+ // It's extremely difficult to say whether any output of a random -+ // number generator is or is not "good", but the odds that 251 bytes -+ // of RNG output are all zero is one in 2**2008, and the odds that -+ // the first 251 bytes of RNG output are equal to the second 251 -+ // bytes of RNG output is also one in 2**2008. (Again, we use an -+ // odd, prime number to trip up implementations that do wide writes.) -+ -+ char prev[251]; -+ memset (prev, 0, 251); -+ -+ if (!get_random_bytes (page + pagesize - 251, 251)) -+ { -+ printf ("ERROR: get_random_bytes(251)/1 = %s\n", strerror (errno)); -+ error_occurred = 1; -+ return; -+ } -+ -+ if (!memcmp (prev, page + pagesize - 251, 251)) -+ { -+ printf ("ERROR: get_random_bytes(251)/1 produced all zeroes\n"); -+ error_occurred = 1; -+ return; -+ } -+ -+ memcpy (prev, page + pagesize - 251, 251); -+ -+ if (!get_random_bytes (page + pagesize - 251, 251)) -+ { -+ printf ("ERROR: get_random_bytes(251)/2 = %s\n", strerror (errno)); -+ error_occurred = 1; -+ return; -+ } -+ -+ if (!memcmp (prev, page + pagesize - 251, 251)) -+ { -+ printf ("ERROR: get_random_bytes(251)/2 produced same output " -+ "as /1\n"); -+ error_occurred = 1; -+ return; -+ } -+ -+ printf ("ok: get_random_bytes(251) smoke test of output\n"); -+} -+ -+static void -+test_fault (char *page, size_t pagesize) -+{ -+ printf ("Testing partially inaccessible output buffer...\n"); -+ bool rv = get_random_bytes (page + pagesize - 64, 128); -+ /* shouldn't ever get here */ -+ error_occurred = 1; -+ if (rv) -+ printf ("ERROR: success (should have faulted)\n"); -+ else -+ printf ("ERROR: failed with %s (should have faulted)\n", -+ strerror (errno)); -+} -+ -+/* In one of the tests above, a segmentation fault is the expected result. */ -+static jmp_buf env; -+static void -+segv_handler (int sig) -+{ -+ siglongjmp (env, sig); -+} -+ -+static void -+expect_no_fault (char *page, size_t pagesize, -+ void (*testfn) (char *, size_t)) -+{ -+ int rv = sigsetjmp (env, 1); -+ if (!rv) -+ testfn (page, pagesize); -+ else -+ { -+ printf ("ERROR: Unexpected %s\n", strsignal (rv)); -+ error_occurred = 1; -+ } -+} -+ -+static void -+expect_a_fault (char *page, size_t pagesize, -+ void (*testfn) (char *, size_t)) -+{ -+ int rv = sigsetjmp (env, 1); -+ if (!rv) -+ { -+ testfn (page, pagesize); -+ printf ("ERROR: No signal occurred\n"); -+ error_occurred = 1; -+ } -+ else -+ { -+ printf ("ok: %s (as expected)\n", strsignal (rv)); -+ } -+} -+ -+int -+main (void) -+{ -+ /* Set up a two-page region whose first page is read-write and -+ whose second page is inaccessible. */ -+ size_t pagesize = (size_t) sysconf (_SC_PAGESIZE); -+ if (pagesize < 256) -+ { -+ printf ("ERROR: pagesize of %zu is too small\n", pagesize); -+ return 1; -+ } -+ -+ char *page = mmap (0, pagesize * 2, PROT_READ|PROT_WRITE, -+ MAP_PRIVATE|MAP_ANON, -1, 0); -+ if (page == MAP_FAILED) -+ { -+ perror ("mmap"); -+ return 1; -+ } -+ memset (page, 'x', pagesize * 2); -+ if (mprotect (page + pagesize, pagesize, PROT_NONE)) -+ { -+ perror ("mprotect"); -+ return 1; -+ } -+ -+ struct sigaction sa, os, ob; -+ sigfillset (&sa.sa_mask); -+ sa.sa_flags = SA_RESTART; -+ sa.sa_handler = segv_handler; -+ if (sigaction (SIGBUS, &sa, &ob) || sigaction (SIGSEGV, &sa, &os)) -+ { -+ perror ("sigaction"); -+ return 1; -+ } -+ -+ expect_no_fault (page, pagesize, test_basic); -+ expect_a_fault (page, pagesize, test_fault); -+ -+ sigaction (SIGBUS, &ob, 0); -+ sigaction (SIGSEGV, &os, 0); -+ -+ return error_occurred; -+} - -From 59680ceac13f85a1506fca87255ea47304a8e493 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Tue, 26 Jun 2018 22:45:01 +0000 -Subject: [PATCH 34/41] crypt.h: introduce CRYPT_GENSALT_IMPLEMENTS_* feature - test macros - -Define CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX and -CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY feature test macros. - -These macros could be checked by portable users of crypt_gensalt* -functions to find out whether null pointers could be specified -as PREFIX and RBYTES arguments. ---- - crypt-base.h | 6 ++++++ - crypt_gensalt.3 | 21 +++++++++++++++++++++ - 2 files changed, 27 insertions(+) - -diff --git a/crypt-base.h b/crypt-base.h -index 565f943..dd27b8e 100644 ---- a/crypt-base.h -+++ b/crypt-base.h -@@ -185,6 +185,12 @@ extern char *crypt_gensalt_ra (const char *__prefix, unsigned long __count, - const char *__rbytes, int __nrbytes) - __THROW; - -+/* These macros could be checked by portable users of crypt_gensalt* -+ functions to find out whether null pointers could be specified -+ as PREFIX and RBYTES arguments. */ -+#define CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX 1 -+#define CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY 1 -+ - /*TRAILER*/ - - #endif /* crypt.h */ -diff --git a/crypt_gensalt.3 b/crypt_gensalt.3 -index 8759011..ebfff28 100644 ---- a/crypt_gensalt.3 -+++ b/crypt_gensalt.3 -@@ -172,6 +172,19 @@ failed to allocate memory for the compiled - string. - .ad b - .hy 1 -+.SH FEATURE TEST MACROS -+The following macros are defined by -+.BR crypt.h : -+.TP -+.B CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX -+A null pointer can be specified as -+.I prefix -+argument. -+.TP -+.B CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY -+A null pointer can be specified as -+.I rbytes -+argument. - .SH PORTABILITY NOTES - The functions - .BR crypt_gensalt ", " crypt_gensalt_rn ", and " crypt_gensalt_ra -@@ -181,6 +194,14 @@ A function with the name - .B crypt_gensalt - also exists on Solaris 10 and newer, but its prototype and semantics differ. - .PP -+The default prefix and auto entropy features are available since libxcrypt -+version 4.0.0. Portable software can use feature test macros to find out -+whether null pointers could be specified as -+.I prefix -+and -+.I rbytes -+arguments. -+.PP - The set of supported hashing methods varies considerably from system - to system. - .SH ATTRIBUTES - -From d077e0bf39c7b4e3443c35ac8abd6eae4489aecd Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Mon, 9 Jul 2018 17:35:38 +0000 -Subject: [PATCH 35/41] Install libcrypt.pc symlink along with libxcrypt.pc - -As the library name differs from the project name, avoid potential -confusion libcrypt.pc vs libxcrypt.pc by installing libcrypt.pc symlink -to libxcrypt.pc file. ---- - Makefile.am | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/Makefile.am b/Makefile.am -index f99f842..945f283 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -36,6 +36,15 @@ libcrypt_la_SOURCES = \ - randombytes.c - - pkgconfig_DATA = libxcrypt.pc -+# Install libcrypt.pc symlink to libxcrypt.pc file. -+.PHONY: install-data-hook-pkgconfig uninstall-hook-pkgconfig -+install-data-hook: install-data-hook-pkgconfig -+uninstall-hook: uninstall-hook-pkgconfig -+install-data-hook-pkgconfig: -+ cd $(DESTDIR)$(pkgconfigdir) && \ -+ $(LN_S) libxcrypt.pc libcrypt.pc -+uninstall-hook-pkgconfig: -+ -rm -f $(DESTDIR)$(pkgconfigdir)/libcrypt.pc - - # Build libcrypt.so.2 if obsolete APIs are excluded, libcrypt.so.1 otherwise. - if ENABLE_OBSOLETE_API - -From 4f22827c619c2196898b32de44bd45ca627de545 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Fri, 22 Jun 2018 00:07:54 +0000 -Subject: [PATCH 36/41] Extend --enable-obsolete-api configure option - -Make vendor specific parts of compatibility ABI that are enabled by ---enable-obsolete-api option configurable. This allows vendors to -enable only those parts of compatibility ABI that are relevant to them. ---- - Makefile.am | 10 ++++++++-- - configure.ac | 37 ++++++++++++++++++++++++++++--------- - gen-map.awk | 29 +++++++++++++++++++++-------- - gen-vers.awk | 26 +++++++++++++++++++------- - libcrypt.map.in | 10 +++++----- - 5 files changed, 81 insertions(+), 31 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index 945f283..be8b585 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -68,13 +68,17 @@ CLEANFILES = libcrypt.map libcrypt.map.T \ - - libcrypt.map: libcrypt.map.in gen-map.awk Makefile - $(AM_V_GEN)LC_ALL=C $(AWK) \ -- -v SYMVER_MIN=$(SYMVER_MIN) -v SYMVER_FLOOR=$(SYMVER_FLOOR) \ -+ -v SYMVER_MIN=$(SYMVER_MIN) \ -+ -v SYMVER_FLOOR=$(SYMVER_FLOOR) \ -+ -v COMPAT_ABI=$(COMPAT_ABI) \ - -f $(srcdir)/gen-map.awk $(srcdir)/libcrypt.map.in > libcrypt.map.T - $(AM_V_at)mv -f libcrypt.map.T libcrypt.map - - crypt-symbol-vers.h: libcrypt.map.in gen-vers.awk Makefile - $(AM_V_GEN)LC_ALL=C $(AWK) \ -- -v SYMVER_MIN=$(SYMVER_MIN) -v SYMVER_FLOOR=$(SYMVER_FLOOR) \ -+ -v SYMVER_MIN=$(SYMVER_MIN) \ -+ -v SYMVER_FLOOR=$(SYMVER_FLOOR) \ -+ -v COMPAT_ABI=$(COMPAT_ABI) \ - -f $(srcdir)/gen-vers.awk \ - $(srcdir)/libcrypt.map.in > crypt-symbol-vers.h.T - $(AM_V_at)mv -f crypt-symbol-vers.h.T crypt-symbol-vers.h -@@ -91,6 +95,7 @@ crypt-hashes.h: hashes.lst gen-hashes.awk Makefile - $(srcdir)/hashes.lst > crypt-hashes.h.T - $(AM_V_at)mv -f crypt-hashes.h.T crypt-hashes.h - -+if ENABLE_COMPAT_SUSE - # When we are being binary compatible, also install symbolic links to - # mimic SUSE's libowcrypt; any program that uses -lowcrypt in its - # build, or already has a NEEDED entry for libowcrypt.so.1, will be -@@ -127,6 +132,7 @@ uninstall-hook-libshared: - $(DESTDIR)$(libdir)/libowcrypt.so.1 - endif - endif -+endif - - check_PROGRAMS = \ - test-alg-des test-alg-hmac-sha1 test-alg-md4 test-alg-md5 \ -diff --git a/configure.ac b/configure.ac -index 274c16a..3b13d9d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -187,20 +187,38 @@ fi - - AC_ARG_ENABLE([obsolete-api], - AS_HELP_STRING( -- [--disable-obsolete-api], -- [do not include compatibility definitions of obsolete APIs -- (fcrypt, encrypt, setkey) in the shared library. -- Breaks binary compatibility with glibc's libcrypt. -- Only affects existing binaries; new programs cannot be -- linked against these functions in any case.] -+ [--enable-obsolete-api[=ARG]], -+ [When set to "yes", include all compatibility interfaces. -+ When set to "alt", include interfaces for compatibility with ALT. -+ When set to "glibc", include interfaces for compatibility with glibc. -+ When set to "owl", include interfaces for compatibility with Owl. -+ When set to "suse", include interfaces for compatibility with SUSE. -+ When set to "no", do not include compatibility definitions of obsolete -+ APIs (fcrypt, encrypt, setkey) in the shared library, which breaks -+ binary compatibility with glibc's libcrypt. Only affects existing -+ binaries; new programs cannot be linked against these compatibility -+ functions in any case. [default=yes]] - ), - [case "${enableval}" in -- yes) enable_obsolete_api=1 ;; -- no) enable_obsolete_api=0 ;; -+ alt|glibc|owl) -+ enable_obsolete_api=1 -+ enable_compat_suse=0 -+ COMPAT_ABI=${enableval} ;; -+ yes|suse) -+ enable_obsolete_api=1 -+ enable_compat_suse=1 -+ COMPAT_ABI=${enableval} ;; -+ no) -+ enable_obsolete_api=0 -+ enable_compat_suse=0 -+ COMPAT_ABI=${enableval} ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-obsolete-api]) ;; - esac], -- [enable_obsolete_api=1] -+ [enable_obsolete_api=1 -+ enable_compat_suse=1 -+ COMPAT_ABI=yes] - ) -+AC_SUBST(COMPAT_ABI) - - AC_ARG_ENABLE([hashes], - AS_HELP_STRING( -@@ -298,6 +316,7 @@ AC_DEFINE_UNQUOTED([ENABLE_OBSOLETE_API], [$enable_obsolete_api], - [Define as 1 if the obsolete APIs (fcrypt, encrypt, setkey) - should be included, 0 otherwise.]) - AM_CONDITIONAL([ENABLE_OBSOLETE_API], [test $enable_obsolete_api = 1]) -+AM_CONDITIONAL([ENABLE_COMPAT_SUSE], [test $enable_compat_suse = 1]) - - # The Makefile needs to know which versions of the library we are building. - AM_CONDITIONAL([ENABLE_STATIC], [test $enable_static = yes]) -diff --git a/gen-map.awk b/gen-map.awk -index f8289e2..025af05 100644 ---- a/gen-map.awk -+++ b/gen-map.awk -@@ -8,10 +8,11 @@ - # details. - - # The .map.in file is the first input file, and we expect the Makefile --# to have set the variables SYMVER_MIN and SYMVER_FLOOR. All symbol --# versions lower than SYMVER_MIN are discarded from the output. --# All symbol versions lower than SYMVER_FLOOR are replaced with --# SYMVER_FLOOR. SYMVER_FLOOR must be greater than or equal to SYMVER_MIN. -+# to have set the variables SYMVER_MIN, SYMVER_FLOOR, and COMPAT_ABI. -+# All compat symbol versions that do not match COMPAT_ABI are ignored. -+# All symbol versions lower than SYMVER_MIN are discarded from the output. -+# All symbol versions lower than SYMVER_FLOOR are replaced with SYMVER_FLOOR. -+# SYMVER_FLOOR must be greater than or equal to SYMVER_MIN. - # - # The ordering of symbol versions is entirely controlled by the %chain - # directive, which must therefore list both all of the versions -@@ -42,11 +43,23 @@ $1 == "%chain" { - - { - for (i = 2; i <= NF; i++) { -- if ($i != "-") { -- if ($i in SYMBOLS) { -- SYMBOLS[$i] = SYMBOLS[$i] SUBSEP $1 -+ sym=$i -+ if (sym != "-") { -+ n=split(sym, a, ":") -+ if (n > 1) { -+ sym="-" -+ for (j = 2; j <= n; j++) { -+ if (COMPAT_ABI == "yes" || COMPAT_ABI == a[j]) { -+ sym=a[1] -+ } -+ } -+ } -+ } -+ if (sym != "-") { -+ if (sym in SYMBOLS) { -+ SYMBOLS[sym] = SYMBOLS[sym] SUBSEP $1 - } else { -- SYMBOLS[$i] = $1 -+ SYMBOLS[sym] = $1 - } - } - } -diff --git a/gen-vers.awk b/gen-vers.awk -index 4870d05..a846a58 100644 ---- a/gen-vers.awk -+++ b/gen-vers.awk -@@ -9,9 +9,9 @@ - # details. - - # The .map.in file is the first input file, and we expect the Makefile --# to have set the variables SYMVER_MIN and SYMVER_FLOOR. See --# libcrypt.map.in and gen-vers.awk for explanations of the format of --# .map.in files. See crypt-port.h for an explanation of how to use -+# to have set the variables SYMVER_MIN, SYMVER_FLOOR, and COMPAT_ABI. -+# See libcrypt.map.in and gen-vers.awk for explanations of the format -+# of .map.in files. See crypt-port.h for an explanation of how to use - # the macros generated by this program. - # - # Note: if you change the format of .map.in files you probably need to -@@ -51,10 +51,22 @@ $1 == "%chain" { - } - } - for (i = 3; i <= NF; i++) { -- if ($i in SYMBOLS) { -- SYMBOLS[$i] = SYMBOLS[$i] SUBSEP $1 -- } else { -- SYMBOLS[$i] = $1 -+ sym=$i -+ n=split(sym, a, ":") -+ if (n > 1) { -+ sym="" -+ for (j = 2; j <= n; j++) { -+ if (COMPAT_ABI == "yes" || COMPAT_ABI == a[j]) { -+ sym=a[1] -+ } -+ } -+ } -+ if (sym != "") { -+ if (sym in SYMBOLS) { -+ SYMBOLS[sym] = SYMBOLS[sym] SUBSEP $1 -+ } else { -+ SYMBOLS[sym] = $1 -+ } - } - } - } -diff --git a/libcrypt.map.in b/libcrypt.map.in -index 18aac79..0989990 100644 ---- a/libcrypt.map.in -+++ b/libcrypt.map.in -@@ -9,12 +9,12 @@ crypt_r XCRYPT_2.0 GLIBC_2.0 - # Actively supported Openwall extensions; never actually added to - # upstream GNU libc, but present in at least Openwall, ALT, and SUSE - # Linux distributions with one or more of these symbol versions --crypt_rn XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 --crypt_gensalt XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 OW_CRYPT_1.0 --crypt_gensalt_rn XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.1 OW_CRYPT_1.0 -+crypt_rn XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.1:alt -+crypt_gensalt XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.1:alt OW_CRYPT_1.0:suse -+crypt_gensalt_rn XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.1:alt OW_CRYPT_1.0:suse - --crypt_ra XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.2 --crypt_gensalt_ra XCRYPT_2.0 GLIBC_2.0 GLIBC_2.2.2 OW_CRYPT_1.0 -+crypt_ra XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.2:alt -+crypt_gensalt_ra XCRYPT_2.0 GLIBC_2.0:owl:suse GLIBC_2.2.2:alt OW_CRYPT_1.0:suse - - # Deprecated interfaces, POSIX and otherwise; also present in GNU libc - # since 2.0 - -From 022c86e681d2497ac02d88ac265d3c7c2d8b4ac5 Mon Sep 17 00:00:00 2001 -From: "Dmitry V. Levin" -Date: Tue, 10 Jul 2018 15:38:15 +0000 -Subject: [PATCH 37/41] .travis.yml: add --enable-obsolete-api=glibc to the - test matrix - ---- - .travis.yml | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/.travis.yml b/.travis.yml -index 31c50fa..db45ded 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -118,6 +118,30 @@ matrix: - env: - - CONF="--enable-obsolete-api --enable-hashes=glibc" - - FCVER="latest" -+ - compiler: gcc -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc" -+ - FCVER="rawhide" -+ - compiler: clang -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc" -+ - FCVER="rawhide" -+ - compiler: gcc -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc" -+ - FCVER="latest" -+ - compiler: clang -+ os: linux -+ services: docker -+ env: -+ - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc" -+ - FCVER="latest" - - before_install: - - for i in `seq 0 99`; do docker pull fedora:$FCVER && i= && break || sleep 1; done; [ -z "$i" ] - -From 430212bcae4b9f31ed12bc52706b313da723c5cb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Fri, 13 Jul 2018 12:21:32 +0200 -Subject: [PATCH 38/41] test-short-outbuf.c: Fix to build on 32 bit arches - ---- - test-short-outbuf.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/test-short-outbuf.c b/test-short-outbuf.c -index 7ab9d11..d928daa 100644 ---- a/test-short-outbuf.c -+++ b/test-short-outbuf.c -@@ -44,8 +44,8 @@ main (void) - ok = false; - } - -- printf ("Test %lu.0: %s, expected: \"%-2s\", got: \"%-2s\"\n", -- i + 1, result, testcases[i].exp_rn, *outbuf); -+ printf ("Test %u.0: %s, expected: \"%-2s\", got: \"%-2s\"\n", -+ (unsigned int)(i + 1), result, testcases[i].exp_rn, *outbuf); - - crypt_ra ("@@", "@@", (void **) outbuf, (int *) j); - -@@ -59,8 +59,8 @@ main (void) - ok = false; - } - -- printf ("Test %lu.1: %s, expected: \"%-2s\", got: \"%-2s\"\n", -- i + 1, result, testcases[i].exp_ra, *outbuf); -+ printf ("Test %u.1: %s, expected: \"%-2s\", got: \"%-2s\"\n", -+ (unsigned int)(i + 1), result, testcases[i].exp_ra, *outbuf); - - free (j); - free (*outbuf); - -From 383b8b86fc9ab960c60d99ad3c82a93404879c57 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Fri, 13 Jul 2018 13:31:07 +0200 -Subject: [PATCH 39/41] crypt-sunmd5.c: Fix possible overflow on 32 bit arches - ---- - crypt-sunmd5.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c -index c294797..c72aff5 100644 ---- a/crypt-sunmd5.c -+++ b/crypt-sunmd5.c -@@ -299,7 +299,7 @@ gensalt_sunmd5_rn (unsigned long count, - bits of entropy are smuggled into the salt via the round number). */ - if (count < 32768) - count = 32768; -- else if (count + 65536 > SUNMD5_MAX_ROUNDS) -+ else if (count > SUNMD5_MAX_ROUNDS - 65536) - count = SUNMD5_MAX_ROUNDS - 65536; - - count += ((unsigned int)rbytes[0]) << 8; - -From f08ac26609d5bceb867f76b78979b1c21ff04206 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Fri, 13 Jul 2018 15:50:34 +0200 -Subject: [PATCH 40/41] crypt-pbkdf1-sha1.c: gensalt should have indentical - output on big endian arches - ---- - crypt-pbkdf1-sha1.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/crypt-pbkdf1-sha1.c b/crypt-pbkdf1-sha1.c -index cf22f67..38ade74 100644 ---- a/crypt-pbkdf1-sha1.c -+++ b/crypt-pbkdf1-sha1.c -@@ -30,6 +30,7 @@ - #include "crypt-port.h" - #include "crypt-private.h" - #include "alg-hmac-sha1.h" -+#include "byteorder.h" - - #include - #include -@@ -227,8 +228,8 @@ gensalt_sha1_rn (unsigned long count, - * dictionary attack by not using the same iteration count for - * every entry. - */ -- uint32_t rounds, random; -- memcpy (&random, rbytes, 4); -+ uint32_t rounds, random = le32_to_cpu (rbytes); -+ - if (count == 0) - count = CRYPT_SHA1_ITERATIONS; - if (count > UINT32_MAX) - -From 8fb52d98e2750cd5302a375727b703b925896f33 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Fri, 13 Jul 2018 11:45:06 -0400 -Subject: [PATCH 41/41] Fix several test failures on x86-64 with -m32. - - - more fixes for crypt-sunmd5.c when 'unsigned long' and 'unsigned - int' are the same - - test-getrandom-fallbacks needs to interpose open64 as well as open - - test-short-outbuf.c can use %zu instead of %lu to avoid casting - - glibc for x86-64/-m32 uses the same symbol versions as glibc/i386 - -also, libcrypt.minver is now in alphabetical order by host_cpu pattern -within each block of architectures with the same minimum symbol version. ---- - Makefile.am | 2 +- - crypt-sunmd5.c | 6 +++--- - libcrypt.minver | 27 ++++++++++++++------------- - test-gensalt.c | 2 +- - test-getrandom-fallbacks.c | 13 +++++++++++++ - test-short-outbuf.c | 8 ++++---- - 6 files changed, 36 insertions(+), 22 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index be8b585..8605ce7 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -204,7 +204,7 @@ test_getrandom_fallbacks_LDADD = randombytes.lo - if HAVE_LD_WRAP - test_getrandom_fallbacks_LDFLAGS = \ - -Wl,--wrap,getentropy -Wl,--wrap,getrandom -Wl,--wrap,syscall \ -- -Wl,--wrap,open -Wl,--wrap,read -Wl,--wrap,close -+ -Wl,--wrap,open -Wl,--wrap,open64 -Wl,--wrap,read -Wl,--wrap,close - endif - - # Every object file depends on crypt-symbol-vers.h and crypt-hashes.h, -diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c -index c72aff5..0c67a67 100644 ---- a/crypt-sunmd5.c -+++ b/crypt-sunmd5.c -@@ -43,7 +43,7 @@ - #define SUNMD5_SALT_LEN 8 - #define SUNMD5_MAX_SETTING_LEN 32 /* $md5,rounds=4294963199$12345678$ */ - #define SUNMD5_BARE_OUTPUT_LEN 22 /* not counting the setting or the NUL */ --#define SUNMD5_MAX_ROUNDS (0xFFFFFFFF - 4096) -+#define SUNMD5_MAX_ROUNDS (0xFFFFFFFFul - 4096) - - /* At each round of the algorithm, this string (including the trailing - NUL) may or may not be included in the input to MD5, depending on a -@@ -302,8 +302,8 @@ gensalt_sunmd5_rn (unsigned long count, - else if (count > SUNMD5_MAX_ROUNDS - 65536) - count = SUNMD5_MAX_ROUNDS - 65536; - -- count += ((unsigned int)rbytes[0]) << 8; -- count += ((unsigned int)rbytes[1]) << 0; -+ count += ((unsigned long)rbytes[0]) << 8; -+ count += ((unsigned long)rbytes[1]) << 0; - - assert (count != 0); - -diff --git a/libcrypt.minver b/libcrypt.minver -index 256a40a..e1896bb 100644 ---- a/libcrypt.minver -+++ b/libcrypt.minver -@@ -31,23 +31,24 @@ - riscv64.* GLIBC_2.27 - nios2.* GLIBC_2.21 - microblaze.* GLIBC_2.18 --powerpc64le.* GLIBC_2.17 - aarch64.* GLIBC_2.17 -+powerpc64le.* GLIBC_2.17 - x86_64.* GLIBC_2.16 /* x32 */ __x86_64__ && ULONG_MAX == UINT_MAX --tilepro.* GLIBC_2.12 - tilegx.* GLIBC_2.12 --m68k.* GLIBC_2.4 /* coldfire */ defined __mcoldfire__ -+tilepro.* GLIBC_2.12 - arm.* GLIBC_2.4 -+m68k.* GLIBC_2.4 /* coldfire */ defined __mcoldfire__ - powerpc64.* GLIBC_2.3 --x86_64.* GLIBC_2.2.5 -+x86_64.* GLIBC_2.2.5 /* 64 */ defined __x86_64__ - s390x.* GLIBC_2.2 --sparc.* GLIBC_2.0 --sh.* GLIBC_2.0 --s390.* GLIBC_2.0 --powerpc.* GLIBC_2.0 --mips.* GLIBC_2.0 --m68k.* GLIBC_2.0 --ia64.* GLIBC_2.0 --i[3-9]86.* GLIBC_2.0 --hppa.* GLIBC_2.0 - alpha.* GLIBC_2.0 -+hppa.* GLIBC_2.0 -+i[3-9]86.* GLIBC_2.0 -+ia64.* GLIBC_2.0 -+m68k.* GLIBC_2.0 -+mips.* GLIBC_2.0 -+powerpc.* GLIBC_2.0 -+s390.* GLIBC_2.0 -+sh.* GLIBC_2.0 -+sparc.* GLIBC_2.0 -+x86_64.* GLIBC_2.0 /* 32 */ -diff --git a/test-gensalt.c b/test-gensalt.c -index 6713387..bbdfedb 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -179,7 +179,7 @@ static const struct testcase testcases[] = - // SHA1/PBKDF always emits a round count, but we need to test its - // behavior on very large inputs. (This number is the largest - // supported round count.) -- { "$md5", sunmd5_expected_output_r, 32, 0, 4294963199 }, -+ { "$md5", sunmd5_expected_output_r, 32, 0, 4294963199ul }, - #endif - #if INCLUDE_sha1 - { "$sha1", sha1_expected_output, 26, 34, 0 }, -diff --git a/test-getrandom-fallbacks.c b/test-getrandom-fallbacks.c -index 8cbab5f..3e7a96a 100644 ---- a/test-getrandom-fallbacks.c -+++ b/test-getrandom-fallbacks.c -@@ -170,6 +170,19 @@ __wrap_open (const char *path, int flags, mode_t mode) - return ret; - } - -+extern int __wrap_open64 (const char *, int, mode_t); -+extern int __real_open64 (const char *, int, mode_t); -+int -+__wrap_open64 (const char *path, int flags, mode_t mode) -+{ -+ int ret = __real_open64 (path, flags, mode); -+ if (ret == -1) -+ return ret; -+ if (!strcmp (path, "/dev/urandom")) -+ urandom_fd = ret; -+ return ret; -+} -+ - extern int __wrap_close (int); - extern int __real_close (int); - int -diff --git a/test-short-outbuf.c b/test-short-outbuf.c -index d928daa..f3f33a0 100644 ---- a/test-short-outbuf.c -+++ b/test-short-outbuf.c -@@ -44,8 +44,8 @@ main (void) - ok = false; - } - -- printf ("Test %u.0: %s, expected: \"%-2s\", got: \"%-2s\"\n", -- (unsigned int)(i + 1), result, testcases[i].exp_rn, *outbuf); -+ printf ("Test %zu.0: %s, expected: \"%-2s\", got: \"%-2s\"\n", -+ i + 1, result, testcases[i].exp_rn, *outbuf); - - crypt_ra ("@@", "@@", (void **) outbuf, (int *) j); - -@@ -59,8 +59,8 @@ main (void) - ok = false; - } - -- printf ("Test %u.1: %s, expected: \"%-2s\", got: \"%-2s\"\n", -- (unsigned int)(i + 1), result, testcases[i].exp_ra, *outbuf); -+ printf ("Test %zu.1: %s, expected: \"%-2s\", got: \"%-2s\"\n", -+ i + 1, result, testcases[i].exp_ra, *outbuf); - - free (j); - free (*outbuf); diff --git a/libxcrypt-4.1.0_fix_automake.patch b/libxcrypt-4.1.0_fix_automake.patch new file mode 100644 index 0000000..035be5e --- /dev/null +++ b/libxcrypt-4.1.0_fix_automake.patch @@ -0,0 +1,63 @@ +From 77bbad4d3aafc20bf8532de2f6215bb8bb4a02a5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= +Date: Fri, 13 Jul 2018 21:58:02 +0200 +Subject: [PATCH] Makefile: Fix warnings from automake + +--- + Makefile.am | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 8605ce7..f5e8df4 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -37,9 +37,11 @@ libcrypt_la_SOURCES = \ + + pkgconfig_DATA = libxcrypt.pc + # Install libcrypt.pc symlink to libxcrypt.pc file. +-.PHONY: install-data-hook-pkgconfig uninstall-hook-pkgconfig ++phony_targets = \ ++ install-data-hook-pkgconfig uninstall-hook-pkgconfig + install-data-hook: install-data-hook-pkgconfig +-uninstall-hook: uninstall-hook-pkgconfig ++uninstall_hook_targets = \ ++ uninstall-hook-pkgconfig + install-data-hook-pkgconfig: + cd $(DESTDIR)$(pkgconfigdir) && \ + $(LN_S) libxcrypt.pc libcrypt.pc +@@ -110,9 +112,11 @@ if ENABLE_COMPAT_SUSE + # shipped libowcrypt.so.1.) + if ENABLE_OBSOLETE_API + if ENABLE_STATIC +-.PHONY: install-exec-hook-libstatic uninstall-hook-libstatic ++phony_targets += \ ++ install-exec-hook-libstatic uninstall-hook-libstatic + install-exec-hook: install-exec-hook-libstatic +-uninstall-hook: uninstall-hook-libstatic ++uninstall_hook_targets += \ ++ uninstall-hook-libstatic + install-exec-hook-libstatic: + cd $(DESTDIR)$(libdir) && \ + $(LN_S) libcrypt.a libowcrypt.a +@@ -120,9 +124,11 @@ uninstall-hook-libstatic: + -rm -f $(DESTDIR)$(libdir)/libowcrypt.a + endif + if ENABLE_SHARED +-.PHONY: install-exec-hook-libshared uninstall-hook-libshared ++phony_targets += \ ++ install-exec-hook-libshared uninstall-hook-libshared + install-exec-hook: install-exec-hook-libshared +-uninstall-hook: uninstall-hook-libshared ++uninstall_hook_targets += \ ++ uninstall-hook-libshared + install-exec-hook-libshared: + cd $(DESTDIR)$(libdir) && \ + $(LN_S) libcrypt.so libowcrypt.so && \ +@@ -215,3 +221,7 @@ endif + # will reveal the direct dependency) but a few don't. + $(libcrypt_la_OBJECTS): crypt-symbol-vers.h crypt-hashes.h + $(test_byteorder_OBJECTS): crypt-symbol-vers.h crypt-hashes.h ++ ++# Add additional targets ++.PHONY: $(phony_targets) ++uninstall-hook: $(uninstall_hook_targets) diff --git a/libxcrypt.spec b/libxcrypt.spec index 3478b04..4ff9884 100644 --- a/libxcrypt.spec +++ b/libxcrypt.spec @@ -18,8 +18,8 @@ Name: libxcrypt -Version: 4.0.1 -Release: 6%{?dist} +Version: 4.1.0 +Release: 1%{?dist} Summary: Extended crypt library for DES, MD5, Blowfish and others # For explicit license breakdown, see the @@ -28,7 +28,7 @@ License: LGPLv2+ and BSD and Public Domain URL: https://github.com/besser82/%{name} Source0: %{url}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch1: %{url}/compare/v4.0.1...develop.patch#/%{name}-4.0.1_to_develop.patch +Patch0: %{url}/commit/77bbad4.patch#/%{name}-4.1.0_fix_automake.patch BuildRequires: fipscheck BuildRequires: libtool @@ -177,6 +177,9 @@ is highly discouraged. %changelog +* Fri Jul 13 2018 Björn Esser - 4.1.0-1 +- New upstream release + * Fri Jul 13 2018 Björn Esser - 4.0.1-6 - Make testsuite fail on error again - Update patch0 with more upstream fixes diff --git a/sources b/sources index 2423c64..dde52ac 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libxcrypt-4.0.1.tar.gz) = d23503a61a89f23e78347314f400dcaac05d17ec35d9233c09dc5b6019d337c15655d288347eb44af168c16a32f72ec66147a24e067c2a025693cdfb30a908b1 +SHA512 (libxcrypt-4.1.0.tar.gz) = a4b0b0fb683df91a01b475ab0b2625d3c5d34c296885b7b23cffb412afb734933f9b314729853e4c58c68934b1c411a27388edf0055f019c9aeef8f1512fb9a6