unit-tests: Created newhope unit-tests
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 9 Aug 2016 18:58:00 +0000 (20:58 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 10 Aug 2016 12:22:00 +0000 (14:22 +0200)
configure.ac
src/libstrongswan/Makefile.am
src/libstrongswan/plugins/newhope/Makefile.am
src/libstrongswan/plugins/newhope/tests/.gitignore [new file with mode: 0644]
src/libstrongswan/plugins/newhope/tests/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/newhope/tests/newhope_tests.c [new file with mode: 0644]
src/libstrongswan/plugins/newhope/tests/newhope_tests.h [new file with mode: 0644]
src/libstrongswan/plugins/newhope/tests/suites/test_newhope_ke.c [new file with mode: 0644]
src/libstrongswan/plugins/newhope/tests/suites/test_newhope_noise.c [new file with mode: 0644]
src/libstrongswan/plugins/newhope/tests/suites/test_newhope_reconciliation.c [new file with mode: 0644]

index 9e22648..39f2586 100644 (file)
@@ -1782,6 +1782,7 @@ AC_CONFIG_FILES([
        src/libstrongswan/plugins/bliss/Makefile
        src/libstrongswan/plugins/bliss/tests/Makefile
        src/libstrongswan/plugins/newhope/Makefile
+       src/libstrongswan/plugins/newhope/tests/Makefile
        src/libstrongswan/plugins/test_vectors/Makefile
        src/libstrongswan/tests/Makefile
        src/libipsec/Makefile
index eee4408..ae7d2ca 100644 (file)
@@ -631,3 +631,7 @@ endif
 if USE_BLISS
   SUBDIRS += plugins/bliss/tests
 endif
+
+if USE_NEWHOPE
+  SUBDIRS += plugins/newhope/tests
+endif
index fc72410..b01987d 100644 (file)
@@ -6,20 +6,28 @@ AM_CFLAGS = \
        $(PLUGIN_CFLAGS) \
        @COVERAGE_CFLAGS@
 
+# these files are also used by the tests, we can't directly refer to them
+# because of the subdirectory, which would cause distclean to fail
+noinst_LTLIBRARIES = libnewhope.la
+libnewhope_la_SOURCES = \
+       newhope_ke.h newhope_ke.c \
+       newhope_noise.h newhope_noise.c \
+       newhope_reconciliation.h newhope_reconciliation.c
+
+libnewhope_la_LIBADD = \
+       $(top_builddir)/src/libstrongswan/math/libnttfft/libnttfft.la
+
 if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-newhope.la
+noinst_LTLIBRARIES += libstrongswan-newhope.la
 else
 plugin_LTLIBRARIES = libstrongswan-newhope.la
 endif
 
 libstrongswan_newhope_la_SOURCES = \
-       newhope_plugin.h newhope_plugin.c \
-       newhope_ke.h newhope_ke.c \
-       newhope_noise.h newhope_noise.c \
-       newhope_reconciliation.h newhope_reconciliation.c
+       newhope_plugin.h newhope_plugin.c
 
 libstrongswan_newhope_la_LDFLAGS = -module -avoid-version
 
-libstrongswan_newhope_la_LIBADD = \
-       $(top_builddir)/src/libstrongswan/math/libnttfft/libnttfft.la
+libstrongswan_newhope_la_LIBADD = libnewhope.la
+
 
diff --git a/src/libstrongswan/plugins/newhope/tests/.gitignore b/src/libstrongswan/plugins/newhope/tests/.gitignore
new file mode 100644 (file)
index 0000000..c06702c
--- /dev/null
@@ -0,0 +1 @@
+newhope_tests
diff --git a/src/libstrongswan/plugins/newhope/tests/Makefile.am b/src/libstrongswan/plugins/newhope/tests/Makefile.am
new file mode 100644 (file)
index 0000000..3992e26
--- /dev/null
@@ -0,0 +1,25 @@
+TESTS = newhope_tests
+
+check_PROGRAMS = $(TESTS)
+
+newhope_tests_SOURCES = \
+       suites/test_newhope_ke.c \
+       suites/test_newhope_noise.c \
+       suites/test_newhope_reconciliation.c \
+       newhope_tests.h newhope_tests.c
+
+newhope_tests_CFLAGS = \
+       -I$(top_srcdir)/src/libstrongswan \
+       -I$(top_srcdir)/src/libstrongswan/tests \
+       -I$(top_srcdir)/src/libstrongswan/math/libnttfft \
+       -I$(top_srcdir)/src/libstrongswan/plugins/newhope \
+       -DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
+       -DPLUGINS=\""${s_plugins}\"" \
+       @COVERAGE_CFLAGS@
+
+newhope_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+newhope_tests_LDADD = \
+       $(top_builddir)/src/libstrongswan/libstrongswan.la \
+       $(top_builddir)/src/libstrongswan/tests/libtest.la \
+       $(top_builddir)/src/libstrongswan/math/libnttfft/libnttfft.la \
+       ../libnewhope.la
diff --git a/src/libstrongswan/plugins/newhope/tests/newhope_tests.c b/src/libstrongswan/plugins/newhope/tests/newhope_tests.c
new file mode 100644 (file)
index 0000000..1cc9a2d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include <test_runner.h>
+
+#include <library.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#include "newhope_tests.h"
+#undef TEST_SUITE
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+       { .suite = x, },
+#include "newhope_tests.h"
+       { .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+       if (init)
+       {
+               char *plugins, *plugindir;
+
+               plugins = lib->settings->get_str(lib->settings,
+                                                                               "tests.load", PLUGINS);
+               plugindir = lib->settings->get_str(lib->settings,
+                                                                               "tests.plugindir", PLUGINDIR);
+               plugin_loader_add_plugindirs(plugindir, plugins);
+               if (!lib->plugins->load(lib->plugins, plugins))
+               {
+                       return FALSE;
+               }
+       }
+       else
+       {
+               lib->processor->set_threads(lib->processor, 0);
+               lib->processor->cancel(lib->processor);
+               lib->plugins->unload(lib->plugins);
+       }
+       return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+       return test_runner_run("newhope", tests, test_runner_init);
+}
diff --git a/src/libstrongswan/plugins/newhope/tests/newhope_tests.h b/src/libstrongswan/plugins/newhope/tests/newhope_tests.h
new file mode 100644 (file)
index 0000000..3f81434
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+TEST_SUITE(newhope_ke_suite_create)
+TEST_SUITE(newhope_noise_suite_create)
+TEST_SUITE(newhope_reconciliation_suite_create)
diff --git a/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_ke.c b/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_ke.c
new file mode 100644 (file)
index 0000000..33b744f
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <newhope_ke.h>
+
+#include <library.h>
+
+#include <time.h>
+
+const int count = 1000;
+
+START_TEST(test_newhope_ke_good)
+{
+       chunk_t i_msg, r_msg, i_shared_secret, r_shared_secret;
+       diffie_hellman_t *i_nh, *r_nh;
+       struct timespec start, stop;
+       int i;
+
+       clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start);
+
+       for (i = 0; i < count; i++)
+       {
+               i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT);
+               ck_assert(i_nh != NULL);
+               ck_assert(i_nh->get_dh_group(i_nh) == NH_128_BIT);
+
+               ck_assert(i_nh->get_my_public_value(i_nh, &i_msg));
+               ck_assert(i_msg.len = 1824);
+
+               r_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT);
+               ck_assert(r_nh != NULL);
+
+               ck_assert(r_nh->set_other_public_value(r_nh, i_msg));
+               ck_assert(r_nh->get_my_public_value(r_nh, &r_msg));
+               ck_assert(r_msg.len == 2048);
+
+               ck_assert(r_nh->get_shared_secret(r_nh, &r_shared_secret));
+               ck_assert(r_shared_secret.len == 32);
+
+               ck_assert(i_nh->set_other_public_value(i_nh, r_msg));
+               ck_assert(i_nh->get_shared_secret(i_nh, &i_shared_secret));
+               ck_assert(i_shared_secret.len == 32);
+               ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
+
+               /* cleanup */
+               chunk_clear(&i_shared_secret);
+               chunk_clear(&r_shared_secret);
+               chunk_free(&i_msg);
+               chunk_free(&r_msg);
+               i_nh->destroy(i_nh);
+               r_nh->destroy(r_nh);
+       }
+
+       clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stop);
+
+       DBG0(DBG_LIB, "%d Newhope DH loops in %d ms\n", count,
+                                 (stop.tv_nsec - start.tv_nsec) / 1000000 +
+                                 (stop.tv_sec - start.tv_sec) * 1000);
+}
+END_TEST
+
+START_TEST(test_newhope_ke_wrong)
+{
+       chunk_t i_msg, r_msg, i_shared_secret, r_shared_secret;
+       diffie_hellman_t *i_nh, *r_nh;
+
+       i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT);
+       ck_assert(i_nh != NULL);
+       ck_assert(i_nh->get_my_public_value(i_nh, &i_msg));
+
+       r_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT);
+       ck_assert(r_nh != NULL);
+       ck_assert(r_nh->set_other_public_value(r_nh, i_msg));
+       ck_assert(r_nh->get_my_public_value(r_nh, &r_msg));
+
+       /* destroy 1st instance of i_nh */
+       i_nh->destroy(i_nh);
+       chunk_free(&i_msg);
+
+       /* create 2nd instance of i_nh */
+       i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT);
+       ck_assert(i_nh != NULL);
+       ck_assert(i_nh->get_my_public_value(i_nh, &i_msg));
+       ck_assert(i_nh->set_other_public_value(i_nh, r_msg));
+
+       ck_assert(r_nh->get_shared_secret(r_nh, &r_shared_secret));
+       ck_assert(i_nh->get_shared_secret(i_nh, &i_shared_secret));
+       ck_assert(!chunk_equals(i_shared_secret, r_shared_secret));
+
+       /* cleanup */
+       chunk_clear(&i_shared_secret);
+       chunk_clear(&r_shared_secret);
+       chunk_free(&i_msg);
+       chunk_free(&r_msg);
+       i_nh->destroy(i_nh);
+       r_nh->destroy(r_nh);
+}
+END_TEST
+
+START_TEST(test_newhope_ke_fail_i)
+{
+       diffie_hellman_t *i_nh;
+       char buf_ff[2048];
+       int i;
+
+       chunk_t i_msg;
+
+       chunk_t r_msg[] = {
+               chunk_empty,
+               chunk_from_chars(0x00),
+               chunk_create(buf_ff, 2047),
+               chunk_create(buf_ff, 2048),
+       };
+
+       memset(buf_ff, 0xff, sizeof(buf_ff));
+
+               for (i = 0; i < countof(r_msg); i++)
+       {
+               i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT);
+               ck_assert(i_nh != NULL);
+               ck_assert(i_nh->get_my_public_value(i_nh, &i_msg));
+               ck_assert(!i_nh->set_other_public_value(i_nh, r_msg[i]));
+               chunk_free(&i_msg);
+               i_nh->destroy(i_nh);
+       }
+}
+END_TEST
+
+START_TEST(test_newhope_ke_fail_r)
+{
+       diffie_hellman_t *r_nh;
+       char buf_ff[1824];
+       int i;
+
+       chunk_t i_msg[] = {
+               chunk_empty,
+               chunk_from_chars(0x00),
+               chunk_create(buf_ff, 1823),
+               chunk_create(buf_ff, 1824),
+       };
+
+       memset(buf_ff, 0xff, sizeof(buf_ff));
+
+       for (i = 0; i < countof(i_msg); i++)
+       {
+               r_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT);
+               ck_assert(r_nh != NULL);
+               ck_assert(!r_nh->set_other_public_value(r_nh, i_msg[i]));
+               r_nh->destroy(r_nh);
+       }
+}
+END_TEST
+
+Suite *newhope_ke_suite_create()
+{
+       Suite *s;
+       TCase *tc;
+
+       s = suite_create("newhope_ke");
+
+       tc = tcase_create("ke_good");
+       test_case_set_timeout(tc, 30);
+       tcase_add_test(tc, test_newhope_ke_good);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("ke_wrong");
+       tcase_add_test(tc, test_newhope_ke_wrong);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("ke_fail_i");
+       tcase_add_test(tc, test_newhope_ke_fail_i);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("ke_fail_r");
+       tcase_add_test(tc, test_newhope_ke_fail_r);
+       suite_add_tcase(s, tc);
+
+       return s;
+}
diff --git a/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_noise.c b/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_noise.c
new file mode 100644 (file)
index 0000000..96dd167
--- /dev/null
@@ -0,0 +1,676 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <newhope_noise.h>
+
+#include <library.h>
+
+static const uint16_t n = 1024;
+static const uint16_t q = 12289;
+
+static const size_t seed_len = 32;
+
+typedef struct {
+       uint8_t key;
+       uint8_t nonce;
+       uint8_t uniform[64];
+       uint32_t poly[1024];
+} noise_t;
+
+static noise_t noises[] = {
+       { 0x00, 0x00,   /* polynomial s */
+         { 0x9f, 0x07, 0xe7, 0xbe, 0x55, 0x51, 0x38, 0x7a, 0x98, 0xba,
+               0x97, 0x7c, 0x73, 0x2d, 0x08, 0x0d, 0xcb, 0x0f, 0x29, 0xa0,
+               0x48, 0xe3, 0x65, 0x69, 0x12, 0xc6, 0x53, 0x3e, 0x32, 0xee,
+               0x7a, 0xed, 0x29, 0xb7, 0x21, 0x76, 0x9c, 0xe6, 0x4e, 0x43,
+               0xd5, 0x71, 0x33, 0xb0, 0x74, 0xd8, 0x39, 0xd5, 0x31, 0xed,
+               0x1f, 0x28, 0x51, 0x0a, 0xfb, 0x45, 0xac, 0xe1, 0x0a, 0x1f,
+               0x4b, 0x79, 0x4d, 0x6f },
+         { 12286, 12288, 12287,     5,     4, 12288, 12286, 12287,     2,     2,
+                   2, 12288,     2, 12284,     1, 12288, 12288, 12288,     6, 12288,
+                   0,     4,     1, 12285, 12286,     2, 12284, 12287,     1,     5,
+                   5, 12286, 12288,     2, 12286,     0,     3,     1,     0,     2,
+                   0,     0,     4, 12283, 12284,     4,     0, 12288,     3, 12288,
+                   0,     4,     1, 12288, 12286,     0,     3,     1, 12286, 12287,
+               12285,     3,     2,     3, 12286,     0,     6,     6, 12288, 12284,
+                   0, 12282,     1,     0,     4,     1,     0,     3,     2,     2,
+                   3,     3,     2, 12288,     3,     1, 12287, 12285,     0, 12288,
+                   0,     0, 12288, 12287, 12284, 12286,     0, 12288,     4,     4,
+               12288,     5, 12286,     2, 12288,     5,     1, 12283,     1, 12288,
+                   1, 12288, 12287, 12285,     2,     2, 12285, 12284,     0, 12285,
+               12287,     0,     1,     0,     2, 12288, 12288, 12287,     0,     4,
+               12288, 12285, 12288,     0,     2,     1, 12287,     3,     1,     3,
+                   5, 12286,     1,     0, 12286,     0,     4,     0, 12288,     1,
+               12288,     4,     5, 12283, 12288,     1,     3, 12283, 12286,     5,
+                   1, 12286, 12287, 12286,     0, 12287, 12285,     1,     0,     0,
+                   1,     3,     0,     0,     0, 12284, 12286,     2,     4, 12288,
+                   6,     1,     2, 12288,     1, 12287, 12286, 12284, 12287,     1,
+                   3, 12284,     0,     0,     6, 12286,     7,     5,     2,     3,
+               12285, 12287, 12285,     2,     3, 12283,     2, 12284, 12288,     3,
+               12288,     1,     4, 12287,     2, 12288, 12288,     1, 12286, 12284,
+                   2,     1,     5, 12286,     0, 12288,     0,     0,     0, 12287,
+                   1,     0,     3,     0,     0,     6,     2, 12283,     1,     3,
+                   3, 12284,     3,     1, 12286,     2, 12288,     0,     6,     1,
+                   1, 12285, 12287, 12288,     4,     2, 12288,     3, 12286, 12288,
+               12287,     3,     3,     2,     7,     4, 12287, 12286, 12287,     2,
+                   2, 12287,     1, 12288,     1, 12287, 12283, 12287, 12288,     1,
+               12283,     0, 12286, 12288,     4, 12287, 12286, 12286,     2,     2,
+               12287,     5, 12288,     4,     0, 12287,     1,     3, 12286,     2,
+                   1,     1, 12288, 12287,     5, 12288,     0,     0,     1,     0,
+               12286,     6,     2,     1,     2,     5, 12286,     6, 12286, 12288,
+                   0, 12286,     3, 12283, 12288, 12284,     0,     7,     2,     6,
+                   1, 12288, 12285, 12284,     1,     0,     0,     2, 12288, 12288,
+               12288,     3,     3,     1,     3, 12286,     4,     3, 12284,     4,
+                   1, 12287, 12287, 12285,     0, 12287, 12287, 12287, 12286, 12288,
+                   1, 12287,     1,     0, 12288,     2,     0,     4,     0, 12287,
+               12285, 12285,     5,     3, 12282,     0, 12287,     5, 12287,     1,
+               12283, 12288, 12288,     3,     1,     1,     3, 12288, 12283,     5,
+               12288, 12288,     5,     5,     1, 12286, 12286, 12288,     1,     2,
+                   1,     3, 12287, 12288, 12284, 12287,     1, 12287,     0, 12286,
+               12285,     1, 12287, 12282, 12286, 12287,     0, 12285,     4,     2,
+                   1, 12282,     0,     1, 12288, 12285, 12284, 12286, 12286, 12287,
+               12288,     1, 12288,     4, 12287,     4, 12287, 12287,     0,     1,
+               12287,     3,     1, 12286, 12286,     4,     6, 12288,     1, 12285,
+               12286, 12287,     0, 12287, 12287,     1, 12286,     5,     0,     2,
+               12283, 12284,     1, 12286,     0, 12287, 12286, 12288,     1,     4,
+                   4, 12283,     2,     6,     1, 12288, 12286,     2,     7,     2,
+                   1, 12288,     5, 12284, 12288, 12288,     1,     7,     3, 12283,
+                   1, 12286,     2, 12288, 12287,     1, 12286,     1, 12286, 12288,
+               12287,     3,     2,     2,     0, 12284, 12287,     1,     1, 12284,
+               12286,     1,     2,     1,     0, 12285,     1,     0,     1,     2,
+                   2,     4, 12288,     1, 12288,     5,     0, 12287, 12288,     2,
+                   0, 12288, 12287,     0, 12288, 12288,     0,     0, 12285,     4,
+                   2, 12288,     0,     2,     0, 12288,     1,     3, 12287, 12288,
+               12288, 12288, 12286,     0, 12285, 12286, 12287,     3,     0, 12286,
+                   2,     1, 12285,     2, 12288,     0,     5,     0,     1, 12288,
+               12288,     4,     3,     3, 12286,     2, 12288,     4, 12288,     6,
+                   2, 12286,     4, 12287,     2, 12287,     0, 12284, 12288,     0,
+               12286, 12288,     3,     4, 12286, 12288,     1,     3, 12286,     3,
+                   4,     1,     1,     6,     3,     1,     1,     0, 12288,     4,
+                   0, 12288,     0,     0,     0, 12288,     2,     4,     2, 12287,
+                   0,     0,     3,     2,     3,     4,     0,     3,     2, 12288,
+                   2,     4,     6, 12286, 12284, 12287,     1,     0,     0,     4,
+                   1,     3, 12282,     1,     2,     2,     0,     3, 12282,     2,
+               12287,     2, 12288,     4, 12288,     3,     3, 12283, 12288, 12288,
+               12286, 12287,     5,     4,     3,     3, 12288, 12284,     2,     2,
+                   0, 12288,     1,     3,     3,     4, 12284, 12288,     0,     1,
+               12284,     0, 12286, 12287,     0,     0, 12287,     0,     1,     6,
+               12288,     1, 12284, 12287, 12282, 12288,     4, 12287,     1, 12286,
+                   1, 12286, 12286,     1,     4,     0, 12288,     1, 12288,     1,
+               12285,     3,     1,     0,     1,     0, 12288, 12287,     2,     2,
+                   0, 12288,     3, 12284,     2, 12288, 12288, 12288, 12287,     3,
+                   3,     0, 12286, 12286,     1,     2, 12286, 12287,     0,     1,
+               12288, 12287, 12287, 12288, 12288,     1,     9,     1, 12288, 12287,
+                   2,     1,     1,     0, 12287, 12287,     2,     2, 12288, 12285,
+                   1, 12287,     4,     0,     2,     1,     1,     3, 12284, 12286,
+                   1,     2, 12288, 12287,     4,     1, 12285,     0,     1,     2,
+               12288,     1,     3,     0, 12286,     0, 12288, 12286, 12287, 12286,
+                   1, 12284,     1,     2,     2, 12288,     0, 12288,     1, 12284,
+                   2,     3, 12287,     1, 12285, 12288,     0,     1, 12284,     2,
+               12288, 12286, 12286,     3, 12288, 12282,     3, 12287, 12288, 12287,
+                   4, 12287,     1,     2,     9, 12283, 12286, 12286,     0,     4,
+               12288, 12288,     4,     0,     1,     1,     2, 12284,     1,     1,
+                   0, 12288,     1,     0, 12287,     1,     1,     5,     2,     1,
+               12288,     3, 12287,     5,     4,     1,     4, 12287, 12285,     3,
+               12286,     1,     3,     0, 12287,     0, 12286, 12287, 12287, 12287,
+                   3,     2, 12286, 12284,     2, 12288,     1,     1, 12288,     3,
+                   1,     3, 12284,     3, 12282, 12288,     3,     0,     2, 12288,
+                   0,     5,     0,     2,     0, 12281, 12285,     4,     3,     4,
+                   2, 12284,     0,     0,     2,     2, 12287, 12284,     2, 12286,
+                   1, 12288,     1, 12286, 12286, 12287,     4,     0,     6,     3,
+                   0,     3, 12288, 12288, 12288, 12287,     3,     1,     1,     1,
+                   2, 12287, 12284,     3, 12286, 12280,     3, 12284, 12287, 12288,
+                   5, 12288, 12284,     2, 12285,     4,     3, 12286,     6,     2,
+                   1, 12287,     0,     1,     2, 12286,     1,     0, 12287,     0,
+                   1,     1, 12286,     2, 12285,     0,     1, 12288,     0,     1,
+               12288,     1, 12288, 12287, 12287, 12285, 12282, 12288,     2, 12288,
+                   2, 12284,     1, 12284, 12287, 12286, 12288,     0, 12288,     1,
+               12283, 12286,     5,     3,     0, 12286, 12286,     3,     1,     0,
+                   1, 12288, 12288,     4,     1, 12286, 12287, 12285,     2,     0,
+                   2, 12287,     1, 12285, 12288, 12286, 12288,     2,     2, 12285,
+                   3, 12286, 12285, 12287 }
+       },
+       { 0x00, 0x01,   /* polynomial e */
+         { 0x46, 0xf0, 0xf6, 0xef, 0xee, 0x15, 0xc8, 0xf1, 0xb1, 0x98,
+               0xcb, 0x49, 0xd9, 0x2b, 0x99, 0x08, 0x67, 0x90, 0x51, 0x59,
+               0x44, 0x0c, 0xc7, 0x23, 0x91, 0x6d, 0xc0, 0x01, 0x28, 0x26,
+               0x98, 0x10, 0x39, 0xce, 0x17, 0x66, 0xaa, 0x25, 0x42, 0xb0,
+               0x5d, 0xb3, 0xbd, 0x80, 0x9a, 0xb1, 0x42, 0x48, 0x9d, 0x5d,
+               0xbf, 0xe1, 0x27, 0x3e, 0x73, 0x99, 0x63, 0x7b, 0x4b, 0x32,
+               0x13, 0x76, 0x8a, 0xaa }, 
+         { 12283,     1, 12288,     4,     0, 12285,     5,     1,     1,     2,
+                   3,     4, 12288,     0,     3,     1,     1,     0, 12286,     6,
+                   1,     0,     1,     0,     4,     2, 12288,     3,     0,     5,
+                   1,     5,     2, 12285,     4, 12288,     3,     2, 12288,     2,
+               12288, 12285, 12287,     6, 12282,     1, 12286,     7, 12287,     4,
+                   2,     2, 12288, 12285,     0,     2,     0, 12288,     1, 12287,
+               12287,     2,     1,     2,     1, 12285, 12288, 12286,     1,     2,
+               12287, 12288, 12288,     1,     0, 12287,     0,     4,     2,     6,
+               12287, 12285, 12283, 12285,     5, 12283, 12286,     1, 12283,     2,
+                   3, 12286, 12285,     2,     5, 12286,     3,     0,     3, 12286,
+                   5, 12285, 12287, 12288,     1,     5,     3,     5,     1,     1,
+                   1, 12288,     5,     0, 12288,     3,     2, 12288, 12285, 12288,
+                   5,     6,     0,     2,     1, 12287, 12288, 12287,     3, 12284,
+                   2,     0,     3,     0,     0, 12288,     0,     2,     2,     2,
+                   0,     1,     2,     2,     0,     0, 12287, 12285,     0,     4,
+                   1, 12283,     3,     5, 12288, 12286, 12287,     6,     2,     0,
+                   0, 12287,     2,     2, 12288,     0,     2, 12288, 12287, 12288,
+               12288,     1, 12288,     1, 12288,     2,     4,     2,     1,     1,
+                   0, 12287,     3,     2,     6,     2,     1, 12288, 12285,     6,
+                   0,     1, 12284, 12287, 12287, 12286,     5,     4,     0,     5,
+               12287, 12286, 12288, 12286,     0,     3,     1, 12287, 12287, 12288,
+               12288, 12286,     1,     0,     3, 12287,     3,     1, 12283,     1,
+               12288,     5,     1,     4, 12286, 12287,     2,     0,     0,     0,
+               12281, 12286,     0,     8,     5,     0,     4,     0, 12287,     5,
+                   1,     3,     2, 12286, 12286, 12288, 12285, 12285, 12287,     0,
+               12284, 12287,     1,     0,     2,     1, 12286, 12288,     2, 12285,
+                   0,     0,     0,     1,     0,     6,     1, 12288, 12287, 12287,
+                   0,     3, 12288, 12288, 12287,     0, 12287,     1,     3,     0,
+                   0, 12286, 12286,     4,     4, 12287,     1,     3,     4, 12287,
+               12284,     2, 12288, 12286, 12283, 12285,     1,     3,     1, 12288,
+                   0,     3,     3, 12284, 12285,     5,     3, 12288,     3,     4,
+                   3,     1, 12288,     0, 12288,     1,     0,     0,     3,     0,
+                   3,     2, 12287, 12288,     0, 12288,     0,     2, 12285,     4,
+                   0, 12287, 12287,     1,     1,     1, 12287, 12285,     4, 12282,
+                   3,     1,     1, 12288,     2,     4, 12285, 12286,     3,     1,
+                   0, 12287, 12283, 12285,     2,     5,     1,     1, 12288, 12288,
+                   0,     8,     3, 12287, 12285, 12287, 12286, 12284,     1, 12286,
+                   1, 12288,     2,     3, 12288, 12288,     2, 12288, 12284, 12285,
+                   0,     3, 12288, 12288,     2,     3,     7, 12287,     3,     3,
+                   3, 12284,     0,     0,     1, 12283,     5,     0,     1, 12288,
+                   3, 12286, 12287, 12286,     0,     0, 12287, 12283,     4, 12283,
+                   0,     0,     3, 12285,     5, 12286, 12282, 12288,     1, 12287,
+               12288,     1,     5,     2, 12287,     2, 12288,     7, 12288,     3,
+                   5,     1,     0, 12287,     1, 12287,     3,     2,     4,     2,
+               12287, 12286, 12288,     2,     5,     1, 12286,     4,     0,     2,
+                   6, 12286,     2, 12286,     3, 12288,     5, 12285,     0,     2,
+               12287,     5, 12286, 12284,     7, 12285, 12286, 12284, 12287,     1,
+               12288, 12284, 12286,     2,     4,     2,     2, 12283, 12286,     2,
+                   2, 12283,     1, 12286,     1,     0, 12284,     3,     0,     4,
+                   1,     0,     4, 12288,     0, 12287, 12287, 12287, 12286, 12284,
+               12288,     3,     1, 12285,     0,     3,     8,     4,     2, 12288,
+                   3, 12287, 12287,     2,     3, 12288, 12286,     2, 12286, 12288,
+                   0,     1, 12287, 12285,     0, 12285, 12288, 12287,     1, 12287,
+                   0, 12284,     0,     1,     1, 12285,     0,     0,     0, 12287,
+               12287,     3,     0,     4, 12288,     1, 12288, 12285, 12283,     0,
+               12286, 12286, 12285, 12285, 12287,     1,     0,     2,     3,     1,
+                   2, 12286, 12288,     3, 12286, 12288, 12288,     6,     2,     2,
+                   0, 12288,     2,     5, 12288,     0, 12284, 12282, 12286,     1,
+               12288, 12288, 12286, 12288,     3, 12286,     2,     0, 12283,     0,
+                   4,     2, 12288,     0, 12286,     0,     4,     3, 12286, 12287,
+                   4, 12288,     3,     2, 12283,     1,     1,     1,     3, 12286,
+                   4,     0, 12288, 12285, 12287,     0,     0, 12286,     4,     0,
+               12286,     2, 12288, 12288, 12285, 12283,     5,     3, 12286, 12288,
+                   4,     1, 12283,     0, 12288,     0, 12287, 12287,     0,     3,
+               12287, 12287,     2,     2,     3,     0,     1,     4, 12288,     3,
+                   3,     0, 12284, 12285,     4, 12288,     1, 12287,     0,     1,
+               12283,     1, 12284, 12287, 12286, 12285,     0,     0,     3, 12285,
+                   3,     1, 12288, 12287, 12284, 12282,     5,     3,     3,     2,
+               12285,     4, 12288,     0,     3, 12288,     4,     0, 12283, 12288,
+                   2, 12285, 12288, 12282,     0,     2, 12285,     3,     1, 12284,
+                   1,     5,     7, 12286,     5, 12285,     1,     2,     0,     4,
+               12283, 12287, 12286,     2, 12280, 12287, 12288,     2, 12285, 12286,
+                   2,     1,     2,     1,     2,     2,     3,     3,     0,     0,
+                   4,     2, 12288, 12286,     4,     0,     1, 12288,     2, 12287,
+               12288, 12288,     1,     3, 12283, 12288,     1, 12287,     1,     1,
+                   3, 12288, 12288,     1,     2,     1,     1, 12283,     7, 12286,
+               12288,     1, 12288, 12287, 12284,     7,     2, 12285, 12286,     0,
+                   0,     0,     2,     4, 12288,     0, 12284, 12285, 12286,     2,
+               12284,     2,     4,     6,     3, 12287, 12288, 12285,     1,     2,
+               12286,     0,     0, 12287, 12288,     0, 12286,     2,     1,     1,
+                   1,     3,     1, 12285,     4,     0, 12287, 12288, 12287,     0,
+               12288, 12287, 12288, 12287, 12288, 12288,     0, 12287, 12284,     0,
+               12288, 12285,     3,     2,     4,     2, 12284,     3,     1,     3,
+                   4, 12288, 12285, 12284, 12287,     1,     4,     0,     2, 12288,
+                   4, 12288, 12287,     3,     1,     0,     0, 12284, 12287,     2,
+                   4, 12287,     2, 12288,     0,     2,     2,     3, 12287, 12286,
+                   8, 12286, 12285,     0, 12285,     2,     3,     5, 12287, 12288,
+                   6, 12288, 12284,     0,     0,     3,     1,     2, 12284,     2,
+                   1,     3,     2,     0,     0, 12288, 12287, 12288,     1, 12288,
+                   4,     3, 12284,     1,     3, 12288, 12283, 12288,     1,     1,
+                   2,     1,     1,     3,     1, 12288,     0, 12288,     2,     0,
+                   0, 12284, 12283,     3, 12288,     0,     2, 12287,     0,     0,
+               12286, 12286,     0,     0,     2,     4, 12288,     1,     2,     3,
+                   2, 12286, 12286,     1,     2,     4, 12288, 12288, 12284, 12287,
+                   6,     2, 12288, 12286,     0,     0,     3, 12286, 12288, 12287,
+               12286, 12287,     3,     1, 12286,     0,     4,     3, 12286,     5,
+                   2,     1, 12287, 12286,     4, 12287,     0,     5, 12288,     0,
+               12288,     2,     2,     1,     1,     0,     0, 12288, 12288, 12288,
+                   0,     0, 12288, 12287,     5,     1, 12288,     1,    10,     1,
+                   0,     0,     2,     2,     2,     0, 12288,     4,     2, 12283,
+                   3,     1,     1, 12285,     2, 12285,     5,     7,     5, 12288,
+                   0, 12287,     5,     1, 12288, 12286, 12287,     0,     0,     0,
+               12287,     1,     3, 12288 }
+       },
+       { 0x01, 0x00,   /* polynomial s' */
+         { 0x3a, 0xeb, 0x52, 0x24, 0xec, 0xf8, 0x49, 0x92, 0x9b, 0x9d,
+               0x82, 0x8d, 0xb1, 0xce, 0xd4, 0xdd, 0x83, 0x20, 0x25, 0xe8,
+               0x01, 0x8b, 0x81, 0x60, 0xb8, 0x22, 0x84, 0xf3, 0xc9, 0x49,
+               0xaa, 0x5a, 0x8e, 0xca, 0x00, 0xbb, 0xb4, 0xa7, 0x3b, 0xda,
+               0xd1, 0x92, 0xb5, 0xc4, 0x2f, 0x73, 0xf2, 0xfd, 0x4e, 0x27,
+               0x36, 0x44, 0xc8, 0xb3, 0x61, 0x25, 0xa6, 0x4a, 0xdd, 0xeb,
+               0x00, 0x6c, 0x13, 0xa0 }, 
+         {     5,     4,     4, 12288, 12286,     1, 12287, 12288,     2, 12288,
+               12288, 12287,     2,     2, 12284, 12288, 12288,     3,     2,     3,
+               12287,     2,     2,     0,     0,     2,     5, 12285,     5, 12287,
+                   2, 12282, 12286,     2,     1,     2,     1,     1, 12288, 12285,
+               12287, 12286,     2,     0,     0, 12285,     0,     0, 12287, 12286,
+               12285, 12286,     2, 12288, 12288,     0,     1,     2, 12286,     2,
+                   1,     0,     0,     2,     1, 12288,     1, 12287,     1,     0,
+                   0,     2, 12285,     2,     2, 12288, 12286,     3, 12287,     0,
+                   1,     1,     0,     2, 12287,     2,     1,     2,     3,     0,
+                   0,     1, 12288, 12288,     2, 12287, 12286, 12286,     6, 12288,
+                   0,     0,     4,     0, 12286,     0,     4, 12288, 12288,     5,
+               12287, 12288, 12285,     2, 12285, 12288,     1,     0,     2, 12288,
+               12286,     1,     3, 12285,     2,     2,     1,     1, 12288, 12288,
+               12287,     1, 12288,     3,     0, 12285,     4, 12285, 12287,     2,
+                   2, 12287, 12287, 12286, 12288, 12284,     2, 12286,     4,     1,
+                   0, 12286, 12284,     3, 12286,     3, 12286,     3,     4,     1,
+               12288, 12282,     2,     2, 12284,     0, 12286, 12283,     3,     0,
+                   4,     2,     4,     2, 12285,    10, 12288,     8,     3,     2,
+                   2,     0,     1,     0,     0, 12286,     2, 12284,     4,     1,
+               12287, 12287,     1,     1, 12286,     1,     0, 12285, 12288, 12286,
+               12287,     2,     1, 12284, 12288, 12285, 12285,     3,     0,     1,
+                   4,     4,     1,     0,     2,     1, 12288,     1, 12287,     0,
+               12286,     4,     2,     3,     3, 12285, 12288, 12288,     5,     2,
+                   0,     4,     3, 12287, 12287,     5,     2,     3, 12284,     0,
+                   8,     1,     1,     0,     5, 12288, 12288, 12288, 12286,     6,
+                   3, 12288, 12286, 12287,     4, 12288,     2, 12288, 12284, 12287,
+                   4, 12288,     0,     0,     3,     0,     4,     4, 12287,     0,
+                   3,     0, 12285, 12287, 12288, 12288,     0,     0, 12287, 12288,
+               12286,     0,     0, 12285, 12288,     4, 12287,     1,     2, 12288,
+               12285,     5,     4, 12283,     2,     0, 12288,     2,     0,     0,
+               12286, 12284,     3,     3,     3, 12287,     1,     1,     0,     1,
+                   3, 12288,     4,     4,     0,     2,     0,     1, 12286, 12284,
+                   2,     2, 12287,     3,     2, 12288,     3, 12286,     2, 12286,
+               12288,     4,     3, 12288,     2, 12288,     2,     1, 12288, 12288,
+                   7, 12288, 12288,     0, 12288,     1, 12284, 12288, 12288, 12287,
+               12287,     1, 12285, 12287, 12287,     1,     0,     2, 12286,     3,
+               12288, 12288, 12287,     3,     5,     0,     0, 12287,     2, 12287,
+               12288,     8, 12287,     1,     2, 12288, 12284,     3,     0, 12287,
+               12284,     3,     0,     2,     1,     3,     4, 12287, 12286, 12288,
+               12286,     0,     0, 12287, 12285,     0, 12286,     2,     1, 12287,
+               12288,     5, 12287, 12287, 12286,     2, 12283,     0,     0, 12286,
+                   2, 12284,     5,     0,     1, 12287,     0,     3,     1, 12285,
+               12288,     0,     3, 12287,     2, 12286,     0,     1, 12288,     1,
+               12284, 12281, 12284, 12288, 12285,     2,     5,     4, 12286,     0,
+               12287, 12288, 12286, 12285,     3, 12282,     1, 12287,     2,     0,
+                   6, 12288,     4, 12286,     3, 12288, 12286, 12284,     3,     1,
+                   6,     3,     2,     1,     2,     1,     1, 12288, 12287,     1,
+                   3,     3,     1,     0,     0, 12288,     3, 12284, 12285, 12284,
+                   1,     3, 12286,     0,     1, 12285, 12287,     1, 12285,     2,
+                   0,     1, 12287,     1,     4,     3,     1, 12287,     0,     5,
+                   1, 12288,     2,     1,     1,     4,     3, 12286,     3,     3,
+                   2, 12287,     3, 12286,     0, 12288, 12285,     2,     3, 12286,
+                   0, 12287,     5,     4,     1,     1, 12287, 12288,     2,     0,
+                   0,     0,     2,     0, 12286,     4, 12288, 12288, 12285, 12286,
+                   2, 12288, 12288,     0, 12288, 12286, 12284, 12287,     1,     5,
+                   0, 12285, 12287,     2,     4,     3, 12285, 12287, 12288,     0,
+               12288, 12287, 12286,     2, 12288, 12286, 12284,     1,     2, 12287,
+                   4,     1,     4,     4, 12284,     2,     0, 12288,     3,     1,
+                   0,     4,     1,     6,     0, 12286, 12288, 12287, 12287,     0,
+               12284, 12285,     2, 12286,     1,     0,     3, 12288,     1,     2,
+               12284, 12286, 12285, 12283, 12285,     0, 12285,     2,     0,     2,
+                   1,     3,     1, 12286, 12288,     1,     4,     0,     0, 12287,
+               12287, 12286,     0,     1, 12286,     0,     2, 12288,     2, 12287,
+                   0,     0, 12286, 12287,     4,     6, 12286,     0, 12288,     0,
+                   0, 12287,     2,     3,     4,     1,     3, 12286,     4,     0,
+               12288, 12286, 12287, 12287, 12288,     4, 12285,     1, 12286, 12286,
+                   2, 12288,     0,     0,     1,     5, 12285,     1, 12281,     3,
+               12281,     2,     3,     0, 12284, 12288,     5,     0,     0, 12288,
+                   0,     0, 12288, 12286,     3, 12287,     0,     2, 12288,     0,
+                   3, 12288, 12286,     0, 12286, 12287, 12284,     0, 12286,     1,
+               12287, 12282, 12287, 12288,     0,     5, 12288,     2,     1, 12288,
+                   1, 12285,     5,     2, 12286, 12285, 12287,     0,     2, 12288,
+                   1, 12288,     1, 12286,     0,     2, 12287, 12287,     6, 12286,
+               12288,     0, 12286,     4,     6, 12287, 12287,     2,     2, 12285,
+                   1, 12288, 12285, 12286,     5, 12288,     1,     2,     1,     7,
+               12286,     5, 12288, 12287, 12286, 12284,     1,     2, 12287,     4,
+                   1,     1,     0,     1,     2, 12285,     2, 12288, 12284,     1,
+                   1, 12287, 12286, 12285, 12287,     1, 12287,     3,     1, 12286,
+                   0, 12286,     3,     3, 12288,     2, 12288,     5, 12288,     1,
+                   2,     0, 12287,     1, 12287,     7,     2,     3,     0, 12287,
+                   2, 12284, 12284, 12281, 12286, 12285, 12287, 12287,     0, 12288,
+                   3,     4,     3,     2,     3,     1, 12288, 12286,     0, 12288,
+               12286,     1, 12286,     6, 12287,     1,     6,     5,     3,     1,
+               12286,     2,     1,     3,     1, 12286, 12285,     3,     2,     0,
+                   0, 12284,     1,     1,     3,     3,     1,     1, 12288,     0,
+               12284,     1, 12288,     0,     0, 12287,     0,     4, 12285,     0,
+                   4, 12283,     1,     1,     0, 12285,     0, 12286,     0,     0,
+                   1,     0, 12286,     0, 12288,     3,     4,     0,     2,     1,
+               12287,     2, 12288,     1,     0, 12288,     0, 12288,     6, 12288,
+               12287, 12286,     3, 12284,     0, 12288, 12284, 12286, 12287, 12288,
+               12288, 12288,     4,     0,     2,     6, 12286,     1,     4, 12288,
+                   2,     1,     0,     5,     2,     1, 12285,     0,     0, 12285,
+                   4, 12286,     5,     1,     3,     2, 12287,     2,     0,     2,
+                   7, 12283, 12288, 12288,     3,     0,     3, 12288,     3, 12286,
+               12288, 12287, 12288,     3,     0,     2,     4,     1, 12284,     2,
+               12288, 12286, 12287,     1,     1, 12288,     0, 12288, 12283,     6,
+                   2,     1, 12288,     3, 12287, 12288,     1,     1, 12285,     0,
+               12286, 12287, 12288,     1,     2, 12287,     0,     4,     0, 12286,
+                   2,     1, 12288, 12285, 12287,     0,     2, 12287,     6,     2,
+                   0, 12287, 12288,     2, 12288, 12284, 12288, 12285,     4,     1,
+               12288, 12284, 12287,     4, 12284,     1,     3, 12284, 12282,     0,
+               12286, 12287,     2, 12286,     3,     4,     2, 12288,     3,     3,
+                   1,     3, 12287, 12283 } 
+       },
+       { 0x01, 0x01,   /* polynomial e' */
+         { 0x58, 0xd8, 0x6a, 0xcd, 0xe2, 0x79, 0x61, 0x98, 0xfd, 0xea,
+               0xcf, 0x2a, 0xc0, 0xfd, 0xf0, 0x72, 0x86, 0x32, 0xdc, 0xe9,
+               0xc6, 0x45, 0x81, 0x80, 0x67, 0x06, 0x72, 0x28, 0xa6, 0xfe,
+               0x41, 0x2b, 0x78, 0x88, 0x58, 0x6d, 0x58, 0x47, 0x3e, 0xb7,
+               0x46, 0x60, 0xd8, 0x2f, 0xa0, 0x83, 0xe4, 0xbc, 0x81, 0xdd,
+               0xc6, 0x29, 0x8b, 0xee, 0xf9, 0xec, 0x90, 0x39, 0x9d, 0x46,
+               0xbf, 0x2d, 0x7c, 0xdf }, 
+         { 12287,     3,     3,     1, 12285,     4,     1,     5, 12287, 12285,
+               12285, 12285,     1, 12288, 12287, 12288,     2,     3, 12283, 12288,
+               12285,     0,     0, 12286, 12287, 12288, 12288, 12288, 12288,     1,
+               12288,     2,     2,     5,     5,     0, 12287, 12286,     3,     3,
+                   2,     2,     1,     0,     2, 12287, 12285,     3,     1,     3,
+                   5,     2, 12287, 12287,     2,     0,     4,     2,     0,     0,
+                   1,     5, 12288,     6,     4, 12287,     1,     0, 12283,     0,
+                   1, 12286,     2,     0,     2,     1, 12284, 12282,     0,     6,
+                   1,     2,     5, 12288,     6, 12288, 12284,     2,     1,     2,
+               12288, 12283, 12288,     3, 12288, 12288,     2, 12286, 12283,     1,
+               12285,     0,     0, 12286, 12288, 12286, 12288, 12286,     4,     0,
+                   1, 12285,     3,     1,     2, 12285, 12287, 12284, 12287, 12285,
+               12286,     1, 12288,     3,     5,     5,     3, 12285, 12286, 12288,
+                   0,     1, 12287, 12284,     2,     4, 12288, 12287,     0, 12288,
+               12288, 12285, 12288, 12284,     3,     0,     2,     0,     2,     0,
+                   1,     1,     1, 12287,     1, 12284, 12285,     0, 12284,     1,
+               12284,     2, 12288,     5,     4,     1,     1, 12284,     1,     3,
+                   2,     6,     3,     2,     3, 12284,     0,     0,     4,     2,
+                   6,     2,     2,     2,     6, 12288,     0,     1, 12286,     1,
+                   5,     1, 12283,     2,     0, 12284,     1, 12286,     4,     1,
+                   2,     4,     6, 12288, 12288, 12284,     1,     0,     3, 12286,
+                   1,     0,     3, 12288, 12287,     2,     2,     0, 12285, 12286,
+                   0, 12288,     4,     2, 12282, 12287,     1, 12288, 12287, 12286,
+               12284,     1,     4,     2,     7, 12288, 12283, 12288,     5, 12288,
+               12288, 12287,     3,     2, 12287,     5, 12287, 12286, 12288, 12287,
+                   0, 12282, 12288, 12288,     0,     3, 12287,     2, 12287, 12284,
+                   6, 12285,     2,     3,     3, 12284,     2,     4, 12286,     5,
+                   0,     2, 12287,     3,     0, 12284, 12286,     0,     2, 12286,
+               12287,     3,     1,     4,     1, 12286, 12288,     1,     2,     0,
+               12285, 12287,     2,     0,     0,     0,     3, 12286, 12287,     2,
+                   0,     0,     0, 12286,     4,     1, 12287,     0,     0,     2,
+                   5,     0, 12284,     1,     1, 12288,     2, 12286, 12288,     2,
+                   2, 12282,     1, 12286,     4, 12286,     3, 12287, 12287, 12286,
+                   5,     5,     0, 12288,     3, 12285,     1, 12287,     7, 12286,
+                   2, 12287,     1, 12285,     2, 12287, 12288,     0,     4, 12281,
+                   0, 12286,     3,     1, 12285,     2,     2, 12285,     5,     0,
+               12285,     2, 12288,     1,     3, 12287,     1, 12288,     1,     5,
+               12287,     1,     0,     3,     2, 12286, 12286, 12288,     3,     0,
+               12287, 12288,     0, 12286, 12285,     0, 12286, 12288,     3, 12287,
+               12288,     2,     6,     0,     2, 12285,     1,     1,     7,     7,
+               12284, 12284,     5,     0, 12288, 12288,     4,     3,     1,     2,
+               12287,     0, 12288, 12284,     2,     5,     1,     2,     0, 12288,
+                   1, 12284,     2,     3,     0, 12287, 12285,     2, 12288, 12288,
+                   7,     1, 12287,     1, 12286,     2,     3,     4, 12288, 12288,
+               12286, 12286,     3, 12288,     1, 12286, 12286,     0, 12283, 12288,
+                   2,     0,     7,     2, 12287,     0,     0, 12286,     4,     1,
+               12288, 12288,     1,     2, 12287, 12282,     3,     5,     0, 12288,
+               12288, 12286, 12286, 12286,     4,     2,     0,     1, 12284,     3,
+               12283,     5, 12287,     2,     2, 12288,     1, 12284,     1,     0,
+                   1,     3, 12288,     2, 12287,     1, 12286, 12288,     0, 12287,
+               12288,     2,     2, 12286,     0, 12287, 12288, 12284,     0,     2,
+                   2,     2,     1,     3, 12285, 12285,     1, 12285,     2,     6,
+                   2,     0, 12288,     0,     0,     3,     2, 12287,     1, 12286,
+                   0, 12287,     0,     1, 12285, 12287,     6, 12288,     2,     0,
+               12286,     2,     4, 12288,     2,     5, 12285, 12286,     0, 12284,
+               12288,     3,     3,     3, 12287,     4,     2,     0, 12283,     2,
+               12287,     0,     1, 12287,     2, 12288, 12287,     3,     2,     7,
+                   7,     1, 12287, 12288,     2,     6,     1,     3,     2,     0,
+                   2,     2,     3, 12288,     3,     4,     2,     0,     5, 12285,
+                   3, 12285,     3, 12285,     1,     1, 12287, 12285,     2, 12285,
+                   5,     0,     7,     2, 12284,     0, 12285,     7,     1, 12288,
+               12288,     0, 12288, 12287,     5,     0,     2,     0,     2, 12286,
+                   1, 12286,     0, 12286, 12285,     4, 12286,     2, 12288, 12287,
+               12287,     1, 12286, 12287, 12287, 12286, 12287, 12288,     6,     5,
+                   2,     5, 12283, 12286, 12286, 12288,     1,     0,     3, 12286,
+                   5,     0, 12287, 12288, 12288, 12287, 12286,     2,     1,     0,
+                   1,     2,     3,     1, 12286,     2,     1,     6, 12288,     1,
+               12286,     1, 12288,     0,     1,     0, 12283,     0,     2, 12288,
+                   3,     1, 12287, 12288,     4,     0,     3, 12286,     0,     1,
+               12283,     4,     1,     4, 12287,     5,     0, 12287, 12288,     3,
+                   3, 12282,     1,     4,     2,     3,     0,     2,     6, 12282,
+               12285, 12288, 12287, 12288,     2, 12285,     1,     0, 12287, 12288,
+               12286,     0,     0,     4, 12288, 12287,     1,     0,     2,     5,
+                   2, 12287,     1,     7, 12284,     0, 12287, 12286,     2,     1,
+               12287,     0,     1, 12284, 12287, 12287, 12285, 12285,     3, 12282,
+               12286,     1,     1, 12288, 12282, 12287,     1,     1,     2,     2,
+                   3,     1, 12287,     5, 12282,     0,     0, 12287,     1,     3,
+               12288,     3, 12285, 12286,     2,     0, 12288, 12288,     5, 12285,
+                   4, 12288, 12287,     0,     1,     4,     1,     2, 12288,     0,
+                   2,     1, 12288,     4,     6, 12288,     1, 12287,     4,     1,
+               12285, 12288,     3,     0, 12288, 12285,     2,     0, 12286,     2,
+                   1, 12288,     1, 12288, 12284,     3,     0,     2,     2, 12288,
+               12287, 12286,     4, 12288,     2,     0,     0,     3,     4,     0,
+               12288, 12282,     6,     2, 12283, 12287,     2,     6,     1,     2,
+               12288,     2, 12283,     3, 12287,     3,     4,     0,     0, 12285,
+                   0, 12288, 12287, 12284, 12286,     3,     1, 12286,     2,     0,
+               12287, 12286, 12286, 12288,     5,     2, 12288, 12286,     0, 12287,
+                   0,     3,     2, 12287, 12286,     0,     1, 12287,     2,     0,
+               12286,     5, 12285, 12288, 12288, 12288, 12286,     4,     1, 12285,
+               12284, 12288, 12286,     1,     1, 12287,     2, 12286,     3,     2,
+               12283, 12283,     4,     2, 12283,     5,     0,     1,     0,     5,
+               12287,     1,     1,     0,     3,    10, 12287,     3, 12288, 12288,
+               12287,     2,     2,     0,     4, 12288, 12283, 12288,     1, 12287,
+                   3,     0,     0,     1, 12288, 12284,     0, 12286, 12287,     0,
+               12287,     2,     1,     7, 12288, 12287,     0,     4, 12287, 12286,
+                   3,     4, 12287, 12288, 12285, 12287, 12288, 12285, 12286,     7,
+                   1,     1, 12288,     3, 12287,     3,     1,     4,     2,     5,
+               12282,     3,     0, 12286, 12288,     0, 12285,     0,     2,     3,
+                   0, 12286,     3,     2, 12285,     0,     0, 12287,     1,     0,
+                   0,     6,     2, 12287, 12284,     7,     5,     0,     1,     6,
+                   2,     4,     1, 12286, 12288,     2, 12287,     3,     4, 12283,
+                   0, 12288,     2,     2, 12286,     0,     2,     2, 12288, 12285,
+               12287, 12285, 12288,     0 }
+       },
+       { 0x01, 0x02,   /* polynomial e'' */
+         { 0x20, 0x37, 0x77, 0x8a, 0x9c, 0x19, 0xde, 0xf0, 0x65, 0x9e,
+               0x0f, 0xa5, 0xfc, 0x0e, 0x78, 0xfe, 0x55, 0x89, 0xc9, 0x88,
+               0x41, 0xa2, 0x5a, 0x1e, 0xa4, 0x66, 0xcd, 0x3a, 0x29, 0x42,
+               0xd1, 0x25, 0xf2, 0x84, 0xd7, 0xee, 0xd5, 0x53, 0x86, 0x5b,
+               0xa3, 0x93, 0x4e, 0xee, 0xc7, 0x5b, 0xe5, 0x52, 0x68, 0x19,
+               0xdf, 0x63, 0xfb, 0x91, 0x3d, 0xe9, 0x5d, 0xd6, 0xeb, 0x81,
+               0x3d, 0xac, 0xf1, 0xad }, 
+         { 12286, 12286,     1, 12287,     1, 12286, 12287, 12287, 12284,     1,
+               12287,     2, 12284,     0,     2, 12288,     0,     1,     0, 12285,
+               12288,     4,     2, 12287, 12282, 12288, 12285, 12288,     2, 12288,
+                   6,     7, 12286, 12286,     1,     4, 12287, 12287,     3,     1,
+                   3,     3,     2, 12285,     0,     1, 12288,     1,     1, 12287,
+                   0,     0,     1,     0, 12287, 12283, 12283, 12288, 12287,     0,
+                   0,     2, 12286,     3,     3,     0, 12286, 12282,     3,     6,
+                   3,     3, 12285,     1,     1, 12288,     1,     0, 12288,     0,
+               12287,     4,     1,     0, 12285, 12288,     1,     1,     1,     3,
+               12286,     0, 12288,     0, 12287, 12287,     3,     5,     1, 12287,
+               12287,     0,     0,     0, 12283,     0,     0, 12288,     0, 12287,
+               12286, 12284, 12286,     0, 12286,     3,     5, 12287,     0, 12287,
+                   1,     3,     2,     6,     1, 12287,     1,     1, 12285,     4,
+               12282, 12288, 12288,     3,     2, 12287,     3,     3, 12288, 12286,
+                   2,     5, 12288, 12287, 12288,     3,     0, 12283,     3,     3,
+                   1,     0, 12288,     2,     2, 12287, 12286,     4, 12287, 12288,
+                   0,     0, 12286,     1,     4,     4, 12286, 12287,     4, 12288,
+                   2,     1,     1, 12288, 12287,     3, 12287, 12286, 12285, 12288,
+                   4,     1,     0, 12287,     3, 12286, 12287,     4,     0, 12287,
+               12286, 12287,     3,     1,     1, 12285, 12287,     0, 12285,     2,
+                   5,     2, 12285,     3,     2, 12285, 12287,     2,     0, 12288,
+                   2,     5,     2, 12283,     1,     1,     0, 12286, 12288,     3,
+                   1, 12286, 12283,     0,     1,     2,     2,     1, 12287, 12287,
+                   4,     4,     1,     0,     0, 12288, 12287, 12284, 12284,     7,
+                   0, 12288,     5,     4, 12288, 12288,     1,     0,     1,     1,
+                   2, 12288, 12288,     5,     1,     0, 12287,     3,     3,     0,
+                   1, 12288, 12288,     3, 12285, 12288,     3,     5,     4,     1,
+               12285, 12285, 12288, 12285, 12288, 12285,     4,     1,     3, 12285,
+                   4,     0, 12288, 12286,     5, 12287, 12285, 12288,     4, 12288,
+                   0, 12287, 12286,     0, 12286, 12283,     0, 12287, 12284,     1,
+               12288, 12288,     3, 12286,     1,     2, 12286,     3,     1, 12285,
+               12286, 12285,     0, 12285, 12288,     0,     2, 12283,     0,     1,
+                   2,     1,     2,     3,     3, 12285,     0,     0,     0, 12288,
+               12283,     4, 12286,     2,     1,     3,     3, 12284,     2,     4,
+                   3, 12286, 12282, 12286,     0, 12286, 12287,     3, 12288, 12288,
+                   2, 12287, 12286,     3,     0, 12286,     1,     1,     0, 12287,
+                   2,     0,     0,     1, 12286,     1,     0, 12283,     0, 12288,
+                   2,     5, 12288, 12287,     2,     1, 12288,     2,     2,     5,
+                   2, 12286, 12286,     2, 12284, 12287,     0, 12284,     0, 12284,
+               12286, 12286, 12288, 12287, 12287,     2,     1, 12287, 12287,     1,
+                   5,     0,     0, 12288,     2, 12285,     6,     2, 12288, 12288,
+               12286,     2, 12285,     0,     0,     0, 12288,     3, 12286,     1,
+                   1,     0,     3,     0, 12286, 12288, 12287,     3,     2, 12287,
+               12288,     1, 12288, 12282,     2,     0, 12288, 12286, 12285, 12281,
+                   4,     1,     7, 12283, 12287, 12288,     1,     6,     0, 12288,
+                   5,     1,     1, 12286, 12286,     0, 12287, 12285, 12287,     1,
+               12288, 12286, 12286, 12288,     2, 12287, 12287, 12288, 12286, 12288,
+               12282, 12284, 12286,     0, 12285, 12285,     3, 12288, 12287, 12288,
+                   2,     0,     2,     0, 12288, 12286,     3, 12288, 12286, 12287,
+                   1,     1,     1,     0,     5,     5, 12285, 12288,     3, 12286,
+                   1,     2, 12285,     1,     4, 12288,     1,     4,     1,     3,
+                   4, 12286,     0,     7,     2, 12288,     2, 12287,     0,     2,
+               12283, 12286,     0, 12288, 12286,     4,     1, 12284,     7, 12285,
+                   0, 12284, 12287,     0,     0,     3,     4, 12284,     0,     1,
+                   0,     1, 12285,     1, 12286, 12284, 12287,     0,     7,     1,
+                   4, 12282, 12288,     0,     2, 12285, 12288, 12287, 12287, 12283,
+                   0,     1,     3, 12285, 12286,     3, 12288, 12288, 12284, 12286,
+               12288,     1,     0,     2, 12287,     0, 12286,     4, 12288,     0,
+               12284,     0,     0,     2, 12286,     0,     0, 12286, 12287,     1,
+               12288,     0, 12284,     1, 12288, 12288,     1,     1, 12282, 12284,
+               12288, 12285, 12285, 12288,     1, 12286,     2,     0,     0, 12284,
+                   2, 12288,     0,     0, 12285,     0,     3,     0,     0, 12285,
+               12286,     5,     3, 12287,     5,     2, 12287,     0,     1, 12286,
+               12287,     1, 12286,     1, 12288,     0,     0, 12282,     5, 12282,
+               12287, 12288, 12287,     1,     0,     3,     4,     6,     1,     1,
+               12287, 12284, 12286, 12287, 12286,     2,     1, 12288,     3,     0,
+                   3,     0, 12286,     1,     0, 12288,     1, 12284,     4,     0,
+                   4, 12288,     1,     4,     1, 12286,     4,     0,     2,     1,
+                   1,     4, 12287,     2,     1, 12288,     4,     3,     2, 12287,
+                   0,     1, 12287,     1, 12285, 12286,     2,     2,     0, 12286,
+               12287,     0, 12288, 12285,     5, 12288,     0,     0, 12288,     3,
+               12288,     0,     4,     0, 12288, 12286, 12287,     0,     0,     2,
+               12283,     0, 12281,     1,     1,     3,     4,     2, 12284,     5,
+               12288,     2,     3,     4, 12287,     3, 12288, 12287, 12288,     2,
+               12286,     2,     0, 12286, 12286,     5, 12288,     2, 12288,     7,
+               12286, 12286,     4, 12288, 12288, 12288,     5, 12287,     7, 12286,
+               12282,     2, 12284,     0, 12288,     0,     2, 12283,     2,     5,
+                   4,     1, 12288, 12283,     5, 12288, 12288,     0,     0,     0,
+                   6,     1, 12286,     6,     4, 12287,     2, 12288, 12287, 12286,
+                   4,     5,     0,     1,     2,     1,     4, 12286,     1,     2,
+                   1,     1,     0, 12288, 12282,     1,     1,     3, 12284, 12288,
+                   0, 12287,     1, 12286, 12288,     6,     1,     5, 12287, 12285,
+                   2, 12288, 12288, 12284,     0, 12287,     2,     3,     5,     1,
+               12286,     1, 12287,     0, 12284,     1,     5, 12283,     1,     1,
+               12287, 12283, 12288,     0, 12287,     3,     0, 12288, 12286, 12287,
+                   8,     0,     0, 12288,     1,     3,     2,     3, 12287,     9,
+                   2,     3,     4, 12288,     3,     0, 12288, 12283,     0,     0,
+                   2,     4, 12287,     2, 12287, 12286, 12287,     2, 12287,     2,
+                   3,     1,     3,     1,     0,     1,     1,     5,     3, 12285,
+                   1, 12281, 12287, 12286,     1,     4, 12287, 12286, 12285,     4,
+                   2,     0, 12288, 12288, 12286, 12287, 12288,     1,     3,     4,
+                   0,     1, 12285,     4,     3, 12284,     1, 12288, 12285, 12288,
+                   0, 12281, 12288, 12285, 12285,     1, 12284, 12286, 12287,     0,
+                   0, 12287,     1, 12282,     4,     4, 12288,     1,     4, 12286,
+                   5,     4,     1,     5,     3,     1,     0,     6, 12288,     0,
+               12288,     2, 12286, 12287,     6,     0, 12288,     0, 12287,     1,
+                   4,     0, 12282,     4,     1, 12286,     1, 12282,     3, 12285,
+               12283, 12286, 12288,     4, 12284, 12286, 12286,     0, 12286,     0,
+                   0,     1, 12286,     1,     1,     4, 12284,     0,     3,     2,
+               12288,     1,     2, 12287,     2,     1, 12288,     0,     1,     2,
+               12286,     0,     6, 12285,     0,     1,     4,     0,     0,     3,
+                   2, 12287, 12285,     7,     1,     3,     1,     0, 12286, 12288,
+                   0, 12287,     1, 12286 }
+       }
+};
+
+START_TEST(test_newhope_noise_uniform)
+{
+       newhope_noise_t *noise;
+       uint8_t seed_buf[seed_len], *uniform;
+       chunk_t seed = { seed_buf, seed_len };
+
+       memset(seed_buf, 0x00, seed_len - 1);
+       seed_buf[seed_len - 1] = noises[_i].key;
+
+       noise = newhope_noise_create(seed);
+       ck_assert(noise != NULL);
+       uniform = noise->get_uniform_bytes(noise, noises[_i].nonce, 64);
+       ck_assert(uniform != NULL);
+       ck_assert(memeq(uniform, noises[_i].uniform, 64));
+       free(uniform);
+       noise->destroy(noise);
+}
+END_TEST
+
+START_TEST(test_newhope_noise_poly)
+{
+       newhope_noise_t *noise;
+       uint8_t seed_buf[seed_len];
+       uint32_t *poly;
+       int i;
+       chunk_t seed = { seed_buf, seed_len };
+
+       memset(seed_buf, 0x00, seed_len - 1);
+       seed_buf[seed_len - 1] = noises[_i].key;
+
+       noise = newhope_noise_create(seed);
+       ck_assert(noise != NULL);
+       poly = noise->get_binomial_words(noise, noises[_i].nonce, n, q);
+       ck_assert(poly != NULL);
+       for (i = 0; i < n; i++)
+       {
+               ck_assert(poly[i] == noises[_i].poly[i]);
+       }
+       free(poly);
+       noise->destroy(noise);
+}
+END_TEST
+
+static size_t seed_lengths[] = { 0, 1, 31, 33 };
+
+START_TEST(test_newhope_noise_fail)
+{
+       newhope_noise_t *noise;
+       chunk_t seed;
+
+       seed = chunk_alloc(seed_lengths[_i]);
+       memset(seed.ptr, 0x00, seed.len);
+
+       noise = newhope_noise_create(seed);
+       ck_assert(noise == NULL);
+       chunk_free(&seed);
+}
+END_TEST
+
+Suite *newhope_noise_suite_create()
+{
+       Suite *s;
+       TCase *tc;
+
+       s = suite_create("newhope_noise");
+
+       tc = tcase_create("noise_uniform");
+       tcase_add_loop_test(tc, test_newhope_noise_uniform, 0, countof(noises));
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("noise_poly");
+       tcase_add_loop_test(tc, test_newhope_noise_poly, 0, countof(noises));
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("noise_fail");
+       tcase_add_loop_test(tc, test_newhope_noise_fail, 0, countof(seed_lengths));
+       suite_add_tcase(s, tc);
+
+       return s;
+}
diff --git a/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_reconciliation.c b/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_reconciliation.c
new file mode 100644 (file)
index 0000000..80172ec
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <newhope_reconciliation.h>
+
+#include <library.h>
+
+static const uint16_t n = 1024;
+static const uint16_t q = 12289;
+
+static const size_t seed_len = 32;
+
+static uint32_t r_v[] = {
+        7832,  2714,  1942, 12135,  6869, 11272, 11601,  1783,  9639,  1465,
+        4603,  8158,  1418,  6162,  3907,  6653,  1091,  3026,  4540,  4797,
+        2751,    29,   768,  5580,  1304,  5262,  1644, 11294, 12257, 10466,
+         170,  8458,  7185,  6850,  8790, 11277, 10980,  5507, 10693,  9766,
+        7230,  3980,   796, 11125,  8042,  9022, 10207,  7577,  5041,   192,
+       10308,  7905,  8520,  3814,  3372, 11772, 11290,   418,  2744,  4782,
+        3072, 10921, 10721,  6100,  1021,  7943,  7426,  2142,  6618,   757,
+        5033,  9336,  9332,  3410,  6613, 11776,  1525,  9567,  5371,  1290,
+        3685, 11054, 11228, 10703,    70, 11215,  8992,  2855,  2962, 10104,
+       10083,  8146,  7599,  3428,  4316, 10056,  1245,  9776,  7867,  1381,
+        6540, 11273,  6626,  3708,  5348,  4521,  3760,  1771, 12037,  2681,
+        3044, 10226,  5133,  5013,  7851,  7187,  1965,  6776,   223,  3003,
+        4800, 10128,  9592,  8917, 10664,  7076,  2081,  5621,  2694,  8245,
+       10979,   929, 10593, 10429,  6890,  6222,  5891,  6633, 12124,  1508,
+         508,  9650,  2480, 10302,  3958,  4519,  5309,  8675,  6963,  5281,
+        8265,  4851,  7173,  2537,  1176,   259,  6422,  6782,  1429,  7231,
+        4948,  8137, 11341, 12090,  5395,  8087,  3098,  6724,  7462,  9973,
+         149,  7331,   562,  9753,  1227,   768,  7520, 12107,  6199,  6503,
+        9876,   306,  3876,  1903,  6306, 10288, 10184,  9401,    68,  5246,
+         630, 10136,   133, 12082,   648,  8537,  3896,  4482, 12011,  5407,
+        5305,  4301,  6551,   714,  5902, 11915,  3121,  5428,  5441,  5140,
+       10139,  2091,   875,  9478, 11576,  8663, 10514,  1018,  8780,  6445,
+        2501,  4204,  1276,  7474, 10594,  3808,  4367, 11469,  4875,  1899,
+        9136,  1507,  6235,  6367,  3851,  7341,  9925,  4629,  9588,  3150,
+        4739,  6109,  4850,  9944, 11565,  4995,  8383,  9623,  6248,  3020,
+        1730,  3368,  3431,  8617,  6478,  7182,  8720,  1927,  6493,  9285,
+        9779,  2800,  3730,  1754,  3772,  3124,  7569, 10008,  9240,  2493,
+        4402,  5851,  2050,  8630,  5054,  8421,  1536,  7671,  5467,  9075,
+        5881,  4355,  4554, 11354,  4048, 10335, 11033,  4252,  2558,  4363,
+       10448,   327,  1675,  4755,  8227,  7705,   398, 10398,  9913,  4129,
+        6571, 10743,   280,  6634,   796,  7264,  3916, 11349,  1415,  1187,
+         692,  9980,  1647,  4267,  1001, 12229,  6040,   268,  1308,   531,
+        3141,  7209,  1941,  4684, 10261,  1415,  8381,  4919, 11450,  1494,
+        8237, 11023,  3380,  4448, 10101,  9232, 11040,  7799,  4958,   741,
+        2234, 10436, 11442,  5073,  2908,  2355,    31,  7222,  5457,  3746,
+        8920,   122,  8960,  5708,  1750, 11161,  4847,  3199,  7954,  2151,
+        9419, 11678,  8997, 12016,  9690,  9605, 10718,  3735,  1617,  9574,
+       10384, 11604,  9311,   687,  7145, 11891,  6529,  5052,  1342,  8735,
+        7644,  6062,  6338,  8563,  2502,  5284,   220,  5224,  3771, 11067,
+       11609,  2972,  3799,  2566,  7488,  6369,  7704,  6095,  3598, 12112,
+        8545,  2026,   746,  3206,  2814,  8740,  1491,  5950,  8413,  4043,
+       12036,  6082,  4131,  1941,  6942,  9396, 11267,  8912,  7344, 10371,
+        9205,  9520, 12038,  4345,  8024, 10999,  8408,  4673,  6682,  8893,
+        8668, 10099,  7658, 11896,  4276,  2042, 10707,  9793,  3152, 11961,
+        3269,  5512,  5736,  5938,  9457, 10439, 10777,  6656,  3174,  9043,
+        6046,  2519, 11912,  5244,  6214,  2071, 11317,  5285,   891,  6184,
+        3819,  1563,  1474,   654,  5147,  2380, 10760,  4816,  3378,  1414,
+        7784, 10067,  1809,  6320,  4789,  9359,  2747,  9424,  9074,  9473,
+        3300,  6244,   104,  7612,  1105,  4276,   573,  1988,   923, 12047,
+        7948,  4860,  3949,  4971,  6956,  2831,  2034,   289, 10946,  6970,
+        3191,  5122,  2175,  1300,  6198,   256,  6433, 11646,  9119,  9723,
+        1046,  5967,  1124,  6449,  2817,   692,  4649,  3089,  5050, 11261,
+        2220,  3052, 12012, 10110,  1394,  2877, 10089, 11696,  4462,  5504,
+          66,  2500,  5384,  7461,  5712,  8649,  9536,  7670,  2385,  3469,
+         782,  2876,  7772,  6118,   142,  5396, 10951, 10556,  3450, 10602,
+        1604,  7909,  3323,    39, 10258,  2262,  7113, 11313, 10203, 10846,
+        9275,  4316,   965,  6006,  4458,  7926,  3171,  1797,  4659,  5336,
+        5543,   250,  9230, 10720, 11970,  4511,  4311, 11763,  1283,  4044,
+        2643,  3744,  4490,  5984,  8868,  8760, 11738,  6037,  9164,  7601,
+        7544, 11117,  7322,  2081,  4034, 10791, 11491,  7027,  1615,  5338,
+        8528,  3424,  2126,   927,  1650,  6068,  3812, 10958,  7574, 11032,
+        6954,  6132,  2598,  9458, 11346,  1974,  3273,  1040, 10331,  8587,
+       11017,  6864,  8246,  5328, 11330,  6779,  8761,  4342,  4595,  8610,
+         161,  4622,  6411, 10708,  7896, 11431, 12097,  9500,  3376,  9561,
+       10730,  2248,  3069,  1434,  8838,   566,  6397,  5881,  4956,  4203,
+        8362,  6047,  3484,  4784,  9901,  8989,   862,  8817, 12186,  9876,
+        9748,  1905,  5696,  9028,  5721,  2940, 10235,  2326,  2134,  6167,
+        1019, 10851,  1253,  5588,  9149,  6532,  3959, 11598,  4068,  3299,
+        8264,  9787,  7089,  2829,  6755,  6156,   455,  5900,  2839,  5921,
+        2140,  7428,  2688, 11175,  9247,  6727, 11711,  1762,  6244,  3336,
+        2308,  9922,  7883,  7007, 10890,  7013,  8452,  2743,  1482,  6927,
+        7846,  6128,  5114,  4868,  7487,  4584,  6785,   460,  6747,  8894,
+        9855, 12242,  3365,  1450,  6614,  3974,  5200,  3247,  2779,  8695,
+         828, 10940,  2304,   376,  3027,  3898, 10351,  1879, 10262,  2512,
+        5487,  4280, 10297,  8480,  9481,  7905,   197,  8361,  4927,   705,
+        9671,  6722,  2589,  8772,  1078,   333,  8696,  6267,  7420,  4471,
+        8994,  5038,  5318,  1846,  2574,  8779, 10724,   825,  7399,  7073,
+        4422,  8385,  5171,  8849, 11344, 10735,  8483,  2241, 11738,  6581,
+       10699,  2777,  6531,  4678,  7608, 10871,  3501,  9239,  7252, 11828,
+        7873,  9606,  4526,  5958,  8505, 11233,  9638,  2421,  5652,  3095,
+        9049, 11347,  6274,  1405, 11114, 11208,  5703, 10774,  3011, 11633,
+        5741,  9601,  5507,  4527,  3501,  5707,  8698,   178, 12091,   325,
+        6056,   635,  3772, 12169, 10509,  6528,  3573,  3675,  3389,  3161,
+        1148,  2687,  3509,  6639, 10452, 11804,  5355,  1085,  9580,  7106,
+        1396,  8279,  4881,  3402,  7803,  8801,  6142,  7623,  4386,  9291,
+        1502,   500, 11809,  6655,  2674, 10061,  1650,  5422,  8936, 10011,
+        1193,  9619,  1435,  8285,  4038,  9984,  9732,  4477,  1251,  7106,
+        7817, 10062,  3378,  5608,  2395,  2563,  1957,  3768,  4160,  7267,
+       11631,  2171,  4771,  6927,  4330, 10482,  6204, 11022,  7895,  1924,
+        3648,  1991,  6628, 10136,  2916,  5416,  7827,  1479,  2312,  9991,
+        7915,  5431, 10911, 10979,  4527,   436, 10521,  5725,  2201, 10198,
+         662,  1691,  8867, 10008,  9359,  5291,   567,  5725, 10329,  4772,
+        2813,  7323,  5646,  1861,  9922,  1831,  9356,  1219,  4107,  9999,
+        4569,  9092,   833,  1602,  4258,  1443,  1484,  4036,  5415,  3767,
+        9992,   412,  9343,  2251, 10513,  9067,  1494, 11893,   744,  1978,
+       11259,  3614,  7459,  5254,  4232,  5148,  4119, 11550,  6425,  4933,
+        4292, 10521,  9657,  9632,  4613,  7738,  5561,  8806,  3501,  3731,
+       11329,  2693, 11581,  6393, 10176, 10773,  1790,  1809,  9186, 12085,
+        5418,  7223,  1077,  1527, 10917,  4236,  7668, 11754,  6655,  7696,
+        1809, 11512,  3618,  5857,  7512,  1044,  7970,  6825,  4897,  2870,
+         126,  8619, 10445,  3883,  4238,  4051,   399,  1580,  9893, 11046,
+        2955,  6520,  5435,  1891,  1254, 12135,  4122, 10512, 11960,  6196,
+        3443, 10118,  1689, 10877
+};
+
+static uint32_t i_v[] = {
+        8355,  2010,  1416, 12110,  6361, 11296, 11668,  1446,  9822,   947,
+        5422,  8211,  1824,  6158,  3458,  6435,   685,  2707,  4804,  4929,
+        3204, 12158,   674,  5703,  1125,  5085,  1358, 10956, 12216, 11164,
+       12112,  8359,  7018,  7038,  9099, 11789, 10574,  5991, 10736,  9335,
+        7898,  4429,   587, 11156,  7912,  9063,  9673,  6792,  5530,   648,
+       10203,  7284,  7935,  4177,  3514, 11488, 10998, 12254,  2913,  4827,
+        2446, 10965, 10718,  5569,  1023,  8150,  7440,  1928,  6384,   802,
+        4726,  9738, 10374,  3842,  6761, 11788,  1133,  9413,  5818,  1099,
+        3710, 11315, 11667, 10285, 12431, 11195,  9193,  2842,  2267,  9902,
+       10076,  7409,  6751,  3748,  4487,  9961,  1547, 10060,  7443,  1276,
+        6827, 10798,  6323,  4038,  5508,  4006,  3300,  1774,   255,  2688,
+        3238, 10275,  4911,  5648,  7842,  7506,  1769,  6425,   195,  3176,
+        4455, 10337,  9451,  8912, 10445,  7646,  2837,  5109,  3033,  8668,
+       10295,   744, 10869, 10204,  6825,  6326,  6299,  7208, 11886,  1246,
+         704,  9626,  2538, 10932,  3903,  4545,  5111,  9006,  6698,  5008,
+        8464,  4679,  7230,  2223,   707,   705,  6592,  6207,  1114,  7645,
+        5374,  7595, 11064,   746,  5585,  8248,  2921,  7004,  6595,  9985,
+         506,  7147,   793,  9605,   596,   962,  8223, 11771,  6438,  6663,
+        9519, 12013,  4302,  2216,  6633, 10351, 10096,  9645,   347,  4601,
+         596, 10448, 12051, 12376,  1544,  8939,  5114,  4052, 11408,  5947,
+        5368,  4270,  6747,   423,  6283, 11211,  2574,  5974,  5533,  5143,
+        9757,  2155,   729,  9776, 11989,  8808, 11057,  1519,  9187,  5996,
+        2966,  3865,  1409,  8023, 10648,  4397,  5082, 10832,  4769,  2068,
+        9226,  1790,  5911,  6534,  3780,  7312,  9388,  5014,  9054,  3445,
+        4659,  6203,  5234,  9490, 11060,  4214,  8978,  9789,  6201,  3088,
+        1988,  3057,  3762,  8725,  7322,  7583,  8233,  1394,  6534,  9221,
+        9736,  2738,  3837,  2595,  4012,  3674,  7505, 10231,  8080,  2402,
+        3977,  5928,  1942,  8421,  5507,  8422,  1238,  6909,  5800,  9613,
+        6083,  4382,  4669, 11670,  4032, 10762, 11623,  4387,  3728,  4656,
+        9701,   722,  1255,  4495,  8158,  7762,   792, 10307,  9813,  3904,
+        6081, 11003, 12045,  6718,  1089,  7327,  4381, 11188,   943,  1740,
+         563, 10251,   756,  5027,   848,   325,  6547, 12288,  1222, 12189,
+        3641,  7314,  2049,  5254, 10043,  1068,  7906,  4741, 11639,  1981,
+        7660, 10911,  2746,  4536, 10068,  9700, 11057,  8114,  5556,   253,
+        2292, 10686, 11848,  5306,  3092,  2570, 12167,  7101,  5245,  3463,
+        8627, 12513,  9010,  5356,  1633, 10462,  4545,  3614,  7245,  1887,
+        9738, 11902,  8716, 12035,  9958,  9421, 11063,  3759,   883,  9754,
+       10730, 11706,  9132,   540,  6726, 11382,  7038,  4407,  1225,  8606,
+        7689,  5894,  6553,  7908,  2454,  4939,   613,  5811,  3580, 11792,
+       11364,  3153,  3698,  2604,  7470,  6053,  7699,  6018,  4289, 11497,
+        8580,  2249,   718,  2444,  2972,  8812,  1710,  6317,  8718,  4194,
+       12288,  5837,  3698,  2216,  7402,  9045, 11194,  8500,  7238, 10686,
+        9409,  9867, 12264,  3859,  7673, 11659,  8496,  4618,  6465,  8811,
+        9114, 10740,  7738, 11850,  4142,  2493, 11136,  9623,  3071, 11701,
+        2925,  5043,  6151,  6221,  9642, 10846, 11145,  6315,  3741,  9123,
+        5131,  2585, 11337,  4786,  5844,  1485, 11505,  5205,   797,  5955,
+        3717,  1756,  1551,  1122,  5057,  2585, 10857,  5129,  3557,  1254,
+        7750,  9688,  2462,  6415,  4345,  9460,  2957,  8793,  9210,  9242,
+        3487,  6506, 11888,  7563,  1078,  4486,   406,  2261,   867, 11965,
+        7979,  4533,  3654,  4747,  6636,  3166,  2114,   380,  9715,  7132,
+        2982,  5024,  1817,  1231,  6210, 12377,  6280, 10882,  9937,  9587,
+         633,  5668,   899,  6176,  2431,   956,  5022,  3094,  4658, 11168,
+        2989,  2654, 11990, 10494,  1691,  3017, 10044, 11882,  4020,  5342,
+       11911,  2426,  5748,  7592,  6340,  9214,  9357,  7169,  2109,  3210,
+         415,  3024,  7791,  5684,   246,  5134, 11335, 10092,  3133, 10427,
+        1502,  7739,  3272,   169,  9521,  2550,  7327, 11309, 10815, 10146,
+        9157,  4579,  1022,  6447,  4233,  8488,  2958,  1715,  4215,  4965,
+        5728,   551,  8942, 10845, 11881,  4472,  4331,   304,  1183,  3798,
+        1968,  3993,  4889,  6145,  8841,  8816, 11283,  6578,  9212,  8161,
+        7003, 11574,  7764,  1678,  4138, 10444, 11880,  7101,  1390,  4743,
+        8320,  3026,  2338,  1203,  1562,  6502,  3103, 10770,  7608, 11097,
+        6745,  6037,  2926,  9489, 10782,  1853,  3482,   524, 11063,  8299,
+       11092,  6838,  7779,  4598, 11245,  7274,  8908,  3886,  4440,  8651,
+       11949,  5344,  6954, 11015,  8333, 11347, 12677,  8716,  3514,  9892,
+       10366,  2029,  2875,  1540,  9013,   250,  6393,  5618,  4565,  3687,
+        8340,  6420,  3632,  5032,  9408,  9738,   961,  8653, 12315, 10459,
+        9883,  2074,  5357,  9341,  4850,  2514,  9746,  2605,  2394,  5928,
+         808, 10443,  1589,  5673,  9176,  6593,  3404, 12254,  4230,  3630,
+        7958, 10065,  7471,  2432,  6626,  6517,   382,  6131,  2888,  5440,
+        1571,  7341,  2841, 11202,  9462,  7180, 11206,  1433,  6183,  3882,
+        2105,  9906,  8076,  7074, 10572,  7262,  8456,  2979,  1095,  6891,
+        8025,  5914,  5380,  4300,  7363,  4989,  6788,  1043,  6836,  8710,
+       10099, 12310,  3997,  2102,  7002,  4041,  4948,  2601,  2958,  8665,
+         984, 10820,  1940,   541,  3377,  3533,  9357,  2049, 10721,  2732,
+        5355,  4280, 10281,  8056,  9557,  7749,   611,  8255,  4854,   708,
+        9199,  7033,  2582,  8343,   820,   944,  8651,  5547,  7052,  4723,
+        8972,  5594,  5314,  1938,  2539,  8789, 10341, 12368,  7475,  6903,
+        4436,  8346,  5391,  8336, 10864, 10397,  8517,  2078, 12127,  6612,
+       10511,  2970,  6576,  5166,  7744, 10934,  3186,  9515,  6831, 12085,
+        7284,  9791,  4755,  6341,  8713, 11526,  9392,  2122,  5743,  2776,
+        9581, 11396,  7006,  1465, 11235, 10997,  5776, 10401,  2929, 11732,
+        5847,  9512,  6068,  3934,  3730,  5813,  9195,   410, 11698,   896,
+        6321,  1310,  3478, 11649, 10201,  6850,  3612,  3451,  3569,  3266,
+         747,  3151,  3352,  6497, 10445, 11501,  5306,  1026,  9712,  7294,
+         813,  8005,  5090,  2905,  7903,  8358,  6290,  7756,  3955,  9471,
+        1858,   699, 11847,  7292,  2165, 10556,  1038,  5289,  8693,  9698,
+        1702, 10228,  1412,  8681,  3330, 10042,  8888,  4257,  1201,  7422,
+        7956, 10019,  3011,  5956,  2188,  2407,  1986,  3847,  4345,  7427,
+       12091,  1763,  3885,  6731,  4172, 10828,  6129, 10972,  7878,  2189,
+        3988,  2125,  6536, 10663,  3100,  5129,  7656,  1053,  2303, 10149,
+        8087,  5666, 11151, 10962,  4905,   779, 10113,  5451,  1509,  9590,
+         735,  1626,  8419, 10607,  9293,  5778,   907,  5527, 10408,  5454,
+        2266,  7131,  6332,  2055, 10105,  1188,  9842,  2059,  4417, 10026,
+        4339,  9779,   680,  1731,  4958,  1589,  1866,  3797,  5058,  3735,
+        9899,   543,  9330,  2436, 10757,  9010,  1270, 12232,  1122,  2222,
+       10945,  3733,  7454,  5251,  4185,  5118,  4331, 12022,  5900,  4767,
+        4393, 10252,  9957,  9653,  4674,  7705,  5694,  9123,  3882,  3137,
+       11627,  2712, 11985,  6346,  9990, 10760,  1869,  1778,  8899, 12168,
+        5207,  7250,  1088,  1131, 11567,  4337,  8286, 11660,  7152,  8010,
+        2286, 11335,  2984,  5740,  7114,   806,  7579,  7119,  5122,  2917,
+         541,  7913, 10555,  3684,  4720,  3954,   517,  1526,  9712, 10854,
+        1921,  6897,  4704,  2141,  1602, 11880,  4548, 10569, 11521,  6408,
+        3609,  9752,  1960, 10934
+};
+
+static uint8_t rbits[] = {
+       0x3f, 0xff, 0xaf, 0x0f, 0x6b, 0xb2, 0xb8, 0x46, 0x53, 0x44,
+       0x95, 0x98, 0x0a, 0x85, 0x0c, 0xfc, 0xc4, 0x86, 0xcc, 0x69,
+       0xc6, 0xd9, 0xfa, 0xee, 0x19, 0xa6, 0x34, 0x0f, 0x35, 0xc4,
+       0xdc, 0x08
+};
+
+static uint8_t r_ref[] = {
+       0, 3, 3, 1, 1, 1, 0, 1, 0, 3, 2, 0, 1, 1, 3, 0, 2, 1, 0, 3, 
+       2, 1, 2, 3, 3, 0, 2, 0, 1, 3, 3, 2, 3, 3, 0, 3, 0, 2, 2, 0, 
+       1, 1, 2, 0, 1, 1, 2, 1, 3, 0, 0, 3, 1, 1, 0, 0, 0, 2, 0, 1, 
+       0, 2, 3, 1, 3, 0, 3, 1, 0, 0, 2, 1, 3, 3, 1, 3, 2, 1, 0, 2, 
+       0, 0, 3, 3, 0, 1, 2, 2, 0, 1, 0, 3, 2, 2, 1, 1, 3, 0, 3, 3, 
+       2, 2, 0, 2, 1, 0, 0, 0, 3, 0, 3, 1, 2, 1, 1, 0, 3, 3, 2, 1, 
+       3, 3, 2, 2, 1, 3, 0, 0, 2, 2, 3, 1, 1, 2, 2, 2, 0, 2, 0, 2, 
+       0, 0, 1, 2, 2, 2, 3, 1, 2, 0, 3, 0, 1, 3, 2, 3, 3, 1, 1, 2, 
+       0, 0, 2, 1, 2, 2, 0, 2, 2, 2, 2, 1, 1, 3, 1, 3, 3, 1, 2, 2, 
+       3, 0, 1, 0, 0, 2, 2, 1, 3, 2, 2, 2, 3, 1, 1, 0, 0, 3, 2, 3, 
+       0, 0, 3, 3, 2, 2, 2, 2, 1, 1, 0, 1, 2, 1, 3, 2, 0, 3, 0, 2, 
+       3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 1, 0, 2, 3, 2, 1, 2, 0, 3, 0, 
+       2, 2, 1, 1, 2, 1, 2, 0, 1, 2, 1, 3, 0, 0, 2, 3, 0, 3, 1, 0, 
+       2, 2, 2, 1, 2, 0, 3, 1, 0, 0, 3, 0, 2, 3, 1, 0, 2, 3, 3, 0, 
+       0, 0, 3, 0, 2, 3, 2, 0, 2, 2, 1, 0, 1, 2, 1, 3, 3, 3, 1, 2, 
+       1, 2, 3, 1, 1, 2, 2, 0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 0, 3, 
+       0, 0, 1, 2, 1, 0, 3, 0, 0, 2, 1, 3, 3, 3, 1, 1, 2, 3, 1, 0, 
+       1, 1, 3, 3, 0, 3, 1, 3, 1, 2, 2, 2, 1, 3, 1, 2, 1, 3, 0, 1, 
+       2, 2, 2, 3, 3, 2, 2, 3, 1, 2, 2, 1, 2, 1, 0, 0, 0, 1, 3, 2, 
+       0, 3, 1, 1, 2, 1, 3, 2, 3, 2, 0, 1, 0, 1, 3, 0, 2, 3, 1, 3, 
+       0, 1, 1, 3, 1, 1, 1, 0, 2, 3, 2, 1, 2, 0, 3, 3, 2, 0, 1, 0, 
+       3, 3, 3, 1, 2, 2, 1, 0, 3, 3, 0, 2, 3, 1, 1, 1, 3, 3, 1, 3, 
+       3, 0, 1, 0, 2, 0, 1, 1, 0, 0, 3, 2, 2, 3, 0, 2, 2, 0, 1, 1, 
+       1, 3, 1, 1, 1, 0, 1, 2, 3, 2, 2, 3, 1, 1, 3, 3, 3, 1, 2, 0, 
+       0, 0, 2, 2, 2, 3, 2, 0, 0, 1, 3, 0, 0, 0, 2, 0, 1, 0, 3, 0, 
+       3, 1, 0, 1, 1, 1, 2, 2, 2, 0, 0, 2, 2, 0, 3, 1, 0, 2, 2, 0, 
+       2, 0, 0, 1, 1, 0, 1, 2, 3, 2, 3, 2, 3, 3, 3, 0, 2, 1, 2, 2, 
+       1, 0, 1, 1, 1, 2, 1, 3, 2, 0, 3, 3, 0, 0, 1, 1, 1, 2, 2, 2, 
+       0, 1, 1, 2, 0, 2, 0, 1, 2, 0, 1, 3, 2, 2, 3, 0, 0, 1, 1, 2, 
+       3, 1, 2, 0, 3, 0, 2, 1, 0, 0, 0, 1, 1, 1, 1, 3, 0, 0, 0, 3, 
+       2, 3, 2, 1, 0, 3, 1, 1, 1, 1, 3, 0, 0, 1, 1, 1, 0, 3, 2, 2, 
+       3, 1, 1, 3, 0, 1, 1, 3, 0, 3, 2, 2, 0, 3, 1, 3, 1, 0, 0, 1, 
+       1, 0, 0, 1, 0, 3, 2, 2, 0, 1, 3, 0, 1, 3, 3, 2, 1, 3, 1, 1, 
+       3, 3, 2, 1, 1, 3, 1, 0, 2, 1, 1, 3, 3, 3, 1, 3, 1, 3, 0, 1, 
+       2, 2, 0, 3, 3, 2, 1, 1, 1, 3, 0, 2, 0, 3, 3, 1, 2, 3, 1, 3, 
+       0, 0, 0, 1, 3, 3, 0, 2, 3, 0, 1, 3, 0, 0, 3, 0, 2, 2, 3, 3, 
+       3, 3, 2, 1, 0, 3, 1, 1, 1, 2, 2, 0, 3, 2, 0, 2, 2, 3, 1, 0, 
+       3, 3, 1, 2, 3, 0, 1, 1, 0, 3, 3, 1, 1, 3, 0, 2, 1, 2, 2, 2, 
+       2, 3, 2, 3, 0, 0, 3, 1, 1, 0, 3, 2, 3, 2, 3, 3, 2, 2, 3, 1, 
+       3, 2, 1, 0, 1, 0, 2, 2, 1, 3, 1, 2, 3, 3, 1, 3, 2, 1, 3, 2, 
+       2, 3, 1, 1, 3, 3, 3, 3, 2, 0, 0, 3, 3, 3, 2, 3, 2, 0, 3, 0, 
+       3, 1, 2, 0, 3, 0, 2, 2, 2, 3, 1, 2, 2, 1, 3, 3, 0, 1, 3, 0, 
+       0, 1, 3, 2, 1, 1, 0, 1, 3, 3, 1, 1, 0, 1, 2, 2, 2, 0, 2, 3, 
+       1, 2, 1, 1, 3, 2, 3, 3, 1, 0, 1, 3, 2, 3, 2, 2, 1, 2, 3, 1, 
+       3, 2, 3, 1, 3, 3, 0, 3, 1, 1, 3, 2, 1, 2, 2, 0, 1, 1, 2, 3, 
+       1, 3, 0, 0, 3, 0, 3, 0, 1, 2, 0, 2, 2, 3, 2, 0, 0, 0, 3, 0, 
+       2, 0, 0, 2, 2, 2, 3, 1, 3, 2, 3, 2, 0, 1, 2, 1, 1, 3, 0, 3, 
+       2, 0, 2, 2, 3, 2, 1, 0, 1, 1, 0, 2, 0, 3, 2, 0, 2, 3, 1, 3, 
+       2, 2, 2, 2, 3, 1, 0, 2, 3, 3, 3, 2, 0, 0, 3, 3, 1, 2, 2, 3, 
+       0, 1, 1, 1, 3, 2, 1, 0, 0, 1, 2, 3, 3, 0, 1, 1, 1, 1, 0, 1, 
+       0, 2, 3, 3, 3, 3, 0, 2, 3, 0, 1, 0, 0, 1, 1, 3, 2, 2, 0, 0, 
+       2, 2, 1, 3
+};
+
+static chunk_t shared_secret = chunk_from_chars(
+       0x14, 0x22, 0x06, 0xe3, 0x48, 0xf3, 0xfa, 0xfc, 0x21, 0x0d,
+       0x5d, 0x51, 0x19, 0x7f, 0x16, 0x4e, 0xe6, 0xd3, 0x10, 0xa9,
+       0xf5, 0xab, 0xfc, 0x96, 0x11, 0x1b, 0xc3, 0x4a, 0x89, 0xf9,
+       0x66, 0x55
+);
+
+START_TEST(test_newhope_rec_good)
+{
+       newhope_reconciliation_t *rec;
+       chunk_t i_shared_secret, r_shared_secret;
+       uint8_t *r;
+
+       rec = newhope_reconciliation_create(n, q);
+       ck_assert(rec != NULL);
+
+       r = rec->help_reconcile(rec, r_v, rbits);
+       ck_assert(memeq(r, r_ref, n));
+
+       r_shared_secret = rec->reconcile(rec, r_v, r);
+       ck_assert(chunk_equals(r_shared_secret, shared_secret));
+
+       i_shared_secret = rec->reconcile(rec, i_v, r);
+       ck_assert(chunk_equals(i_shared_secret, shared_secret));
+
+       /* cleanup */
+       rec->destroy(rec);
+       chunk_free(&i_shared_secret);
+       chunk_free(&r_shared_secret);
+       free(r);
+}
+END_TEST
+
+Suite *newhope_reconciliation_suite_create()
+{
+       Suite *s;
+       TCase *tc;
+
+       s = suite_create("newhope_reconciliation");
+
+       tc = tcase_create("rec_good");
+       tcase_add_test(tc, test_newhope_rec_good);
+       suite_add_tcase(s, tc);
+
+       return s;
+}